You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(57) |
Oct
|
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(36) |
Dec
(7) |
| 2007 |
Jan
(48) |
Feb
(10) |
Mar
(17) |
Apr
(8) |
May
(35) |
Jun
(28) |
Jul
(50) |
Aug
(71) |
Sep
(40) |
Oct
(19) |
Nov
(22) |
Dec
(143) |
| 2008 |
Jan
(184) |
Feb
(549) |
Mar
(381) |
Apr
(388) |
May
(148) |
Jun
(128) |
Jul
(502) |
Aug
(243) |
Sep
(136) |
Oct
(327) |
Nov
(252) |
Dec
(475) |
| 2009 |
Jan
(344) |
Feb
(185) |
Mar
(338) |
Apr
(826) |
May
(1559) |
Jun
(1429) |
Jul
(817) |
Aug
(451) |
Sep
(639) |
Oct
(935) |
Nov
(1222) |
Dec
(826) |
| 2010 |
Jan
(552) |
Feb
(532) |
Mar
(355) |
Apr
(206) |
May
(162) |
Jun
(203) |
Jul
(168) |
Aug
(232) |
Sep
(270) |
Oct
(259) |
Nov
(439) |
Dec
(468) |
| 2011 |
Jan
(224) |
Feb
(249) |
Mar
(278) |
Apr
(381) |
May
(316) |
Jun
(637) |
Jul
(544) |
Aug
(465) |
Sep
(159) |
Oct
(440) |
Nov
(139) |
Dec
|
| 2012 |
Jan
(204) |
Feb
(383) |
Mar
(295) |
Apr
(196) |
May
(590) |
Jun
(158) |
Jul
(167) |
Aug
(177) |
Sep
(179) |
Oct
(301) |
Nov
(144) |
Dec
(173) |
| 2013 |
Jan
(299) |
Feb
(120) |
Mar
(238) |
Apr
(140) |
May
(69) |
Jun
(133) |
Jul
(160) |
Aug
(107) |
Sep
(164) |
Oct
(196) |
Nov
(105) |
Dec
(74) |
| 2014 |
Jan
(205) |
Feb
(156) |
Mar
(175) |
Apr
(181) |
May
(162) |
Jun
(158) |
Jul
(117) |
Aug
(109) |
Sep
(148) |
Oct
(106) |
Nov
(82) |
Dec
(72) |
| 2015 |
Jan
(191) |
Feb
(205) |
Mar
(197) |
Apr
(163) |
May
(136) |
Jun
(36) |
Jul
(79) |
Aug
(55) |
Sep
(64) |
Oct
(146) |
Nov
(142) |
Dec
(78) |
| 2016 |
Jan
(65) |
Feb
(190) |
Mar
(53) |
Apr
(38) |
May
(95) |
Jun
(53) |
Jul
(58) |
Aug
(113) |
Sep
(96) |
Oct
(59) |
Nov
(136) |
Dec
(124) |
| 2017 |
Jan
(80) |
Feb
(109) |
Mar
(163) |
Apr
(78) |
May
(61) |
Jun
(73) |
Jul
(29) |
Aug
(47) |
Sep
(60) |
Oct
(76) |
Nov
(48) |
Dec
(35) |
| 2018 |
Jan
(138) |
Feb
(84) |
Mar
(109) |
Apr
(49) |
May
(24) |
Jun
(62) |
Jul
(96) |
Aug
(116) |
Sep
(53) |
Oct
(99) |
Nov
(80) |
Dec
(88) |
| 2019 |
Jan
(100) |
Feb
(141) |
Mar
(72) |
Apr
(174) |
May
(129) |
Jun
(102) |
Jul
(52) |
Aug
(45) |
Sep
(28) |
Oct
(43) |
Nov
(78) |
Dec
(47) |
| 2020 |
Jan
(113) |
Feb
(72) |
Mar
(94) |
Apr
(141) |
May
(82) |
Jun
(68) |
Jul
(125) |
Aug
(76) |
Sep
(33) |
Oct
(184) |
Nov
(61) |
Dec
(95) |
| 2021 |
Jan
(109) |
Feb
(77) |
Mar
(145) |
Apr
(116) |
May
(134) |
Jun
(113) |
Jul
(71) |
Aug
(118) |
Sep
(116) |
Oct
(92) |
Nov
(124) |
Dec
(68) |
| 2022 |
Jan
(57) |
Feb
(61) |
Mar
(57) |
Apr
(74) |
May
(86) |
Jun
(80) |
Jul
(43) |
Aug
(85) |
Sep
(120) |
Oct
(88) |
Nov
(100) |
Dec
(108) |
| 2023 |
Jan
(39) |
Feb
(56) |
Mar
(92) |
Apr
(81) |
May
(84) |
Jun
(72) |
Jul
(182) |
Aug
(82) |
Sep
(54) |
Oct
(68) |
Nov
(67) |
Dec
(75) |
| 2024 |
Jan
(79) |
Feb
(65) |
Mar
(42) |
Apr
(47) |
May
(68) |
Jun
(111) |
Jul
(43) |
Aug
(73) |
Sep
(100) |
Oct
(35) |
Nov
(100) |
Dec
(99) |
| 2025 |
Jan
(71) |
Feb
(68) |
Mar
(44) |
Apr
(40) |
May
(92) |
Jun
(45) |
Jul
(86) |
Aug
(60) |
Sep
(76) |
Oct
(69) |
Nov
(102) |
Dec
(43) |
| 2026 |
Jan
(51) |
Feb
(81) |
Mar
(62) |
Apr
(48) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <ge...@op...> - 2026-04-24 11:51:14
|
This is an automated email from Gerrit. "Evgeniy Naydanov <eu...@gm...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9587 -- gerrit commit 0339e4ad884992457886147323fa4e516e2e321e Author: Evgeniy Naydanov <eu...@gm...> Date: Thu Mar 12 14:52:21 2026 +0300 target/riscv: drop version-specific `arch_state()` Drop these placeholders. This is a part of the effort to eliminate "fake" `riscv013_target` and `riscv011_target` `target_type`s. Link: http://review.openocd.org/id/Ied5756fb61bceb9b428a54b7fffb02818f94d935 Change-Id: I055ce3114178cc870a6679aa91bc5477870bbeea Signed-off-by: Evgeniy Naydanov <eu...@gm...> diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index 2bef2228e1..8fd3792bf1 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -2347,11 +2347,6 @@ static int access_memory(struct target *target, const struct riscv_mem_access_ar return read_memory(target, args); } -static int arch_state(struct target *target) -{ - return ERROR_OK; -} - static COMMAND_HELPER(riscv011_print_info, struct target *target) { /* Abstract description. */ @@ -2472,6 +2467,4 @@ struct target_type riscv011_target = { .assert_reset = assert_reset, .deassert_reset = deassert_reset, - - .arch_state = arch_state, }; diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 50e0f83dd8..4c5159fb87 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -5076,10 +5076,6 @@ static unsigned int riscv013_get_progbufsize(const struct target *target) return r->progbufsize; } -static int arch_state(struct target *target) -{ - return ERROR_OK; -} struct target_type riscv013_target = { .name = "riscv", @@ -5094,8 +5090,6 @@ struct target_type riscv013_target = { .assert_reset = assert_reset, .deassert_reset = deassert_reset, - - .arch_state = arch_state }; /*** 0.13-specific implementations of various RISC-V helper functions. ***/ diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index e92366d446..1c9ae812ee 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -3565,11 +3565,7 @@ static int riscv_arch_state(struct target *target) target_name(target), debug_reason_name(target), semihosting_active ? " Semihosting is active." : ""); - struct target_type *tt = get_target_type(target); - if (!tt) - return ERROR_FAIL; - assert(tt->arch_state); - return tt->arch_state(target); + return ERROR_OK; } /* Algorithm must end with a software breakpoint instruction. */ -- |
|
From: <ge...@op...> - 2026-04-23 19:13:34
|
This is an automated email from Gerrit. "Name of user not set <wil...@gm...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9586 -- gerrit commit e37057465e6fe31036447986ec47cbf28db35684 Author: William Markezana <wil...@gm...> Date: Fri Apr 10 12:45:43 2026 -0400 jtag/drivers: add T-Head CK-Link JTAG adapter driver Add support for the T-Head CK-Link Lite V2 probe family, including the Bouffalo Lab BL616/BL702 CK-Link clones used as built-in debuggers on BL618/BL702 evaluation boards. The wire protocol is a framed command format over USB bulk endpoints, reverse-engineered from T-Head's DebugServer binary. The driver implements: - Full DebugServer init sequence: selfreg setup, operational clock, 5-wire -> 2-wire -> 5-wire mode toggle (effective TAP reset). - JTAG_SCAN via the probe's single-entry batch opcode with IR caching across execute_queue boundaries; end-of-queue flush populates the IR scan's in_value with hardware-captured Capture-IR data. - Opcode-aware response-frame checksum validation. Selfreg reads use sum-mod-256; JTAG batch responses exclude the last dr_tdo byte. - Clock-divider control (freq_kHz = 48000 / (N+1)) with once-warning clamp when the requested speed exceeds the DebugServer-validated ceiling (2526 kHz). - libusb serial-number filter via adapter_get_required_serial() and kernel-driver auto-detach on Linux. - TCL command 'cklink vid_pid (vid pid)+' to override defaults. Known protocol limitations, surfaced as one-time warnings rather than silent data loss: - Scans exceed 255 bits: the batch opcode encodes bit-counts in single bytes. Clamp + TDI pass-through for the un-shifted portion, which gives OpenOCD's bypass chain-length probe the expected end-of-chain marker. - Back-to-back IR scans: the batch opcode requires both IR and DR phases; mid-queue flushing a deferred IR with a dummy DR would trigger spurious DMI transactions. Single-TAP chains only. - JTAG_TMS, JTAG_PATHMOVE: no TMS-sequence opcode exposed. Return ERROR_JTAG_NOT_IMPLEMENTED. - RTCK: not supported, return ERROR_JTAG_NOT_IMPLEMENTED. Tested against BL618 (VID 0x42bf, PID 0xb210) and BL702 eval boards: IDCODE read, RISC-V DM examine, halt, register read, memory read, single-step, hardware breakpoints, GDB RSP server all functional. Change-Id: If6adaec0445748f3e97078bf980c502eff4d5001 Signed-off-by: William Markezana <wil...@gm...> diff --git a/NEWS b/NEWS index 9db6c5feee..4b77a446d1 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ This file includes highlights of the changes made in the OpenOCD source archive release. JTAG Layer: + * Added support for T-Head CK-Link Lite JTAG adapters, including the + Bouffalo Lab BL616/BL702 clone probes (BL618 eval board debugger). Boundary Scan: diff --git a/configure.ac b/configure.ac index 0d5f0eb354..515f4af119 100644 --- a/configure.ac +++ b/configure.ac @@ -128,6 +128,7 @@ m4_define([USB1_ADAPTERS], [[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]], [[ftdi_cjtag], [cJTAG (OScan1, JScan3) tunneled thru MPSSE], [FTDI_CJTAG]], [[ch347], [CH347 based devices], [CH347]], + [[cklink], [T-Head CK-Link JTAG Probe], [CKLINK]], [[stlink], [ST-Link Programmer], [HLADAPTER_STLINK]], [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]], [[ulink], [Keil ULINK JTAG Programmer], [ULINK]], diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules index 151b4e2c06..0f49e1a2c0 100644 --- a/contrib/60-openocd.rules +++ b/contrib/60-openocd.rules @@ -269,4 +269,8 @@ ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2750", MODE="660", GROUP="plugdev", # CMSIS-DAP compatible adapters ATTRS{product}=="*CMSIS-DAP*", MODE="660", GROUP="plugdev", TAG+="uaccess" +# T-Head CK-Link Lite and Bouffalo Lab BL616/BL702 clones +ATTRS{idVendor}=="32bf", ATTRS{idProduct}=="b210", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="42bf", ATTRS{idProduct}=="b210", MODE="660", GROUP="plugdev", TAG+="uaccess" + LABEL="openocd_rules_end" diff --git a/doc/openocd.texi b/doc/openocd.texi index a21a3e4bda..d016cc5d3c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2615,6 +2615,24 @@ ch347 device_desc "EasyDevKit" @end deffn @end deffn +@deffn {Interface Driver} {cklink} +Driver for the T-Head CK-Link Lite V2 JTAG probe and Bouffalo Lab +BL616/BL702 clones, including the built-in debugger on Bouffalo BL618 +evaluation boards. Communication is over USB bulk endpoints using a +T-Head DebugServer-compatible framed command protocol. + +The driver only supports JTAG transport and a single-TAP chain. The +probe runs at a fixed clock; @command{adapter speed} requests are +accepted but ignored (with a one-time warning). @command{JTAG_TMS} and +@command{JTAG_PATHMOVE} are not supported by this probe's protocol. + +@deffn {Config Command} {cklink vid_pid} [vid pid]+ +Override the built-in VID/PID table. By default the driver matches +0x42bf/0xb210 (Bouffalo) and 0x32bf/0xb210 (T-Head). Up to eight +@var{vid}/@var{pid} pairs may be specified. +@end deffn +@end deffn + @deffn {Interface Driver} {cmsis-dap} ARM CMSIS-DAP compliant based adapter v1 (USB HID based) or v2 (USB bulk or TCP/IP). diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index 5216e5d774..ad08b0e0c8 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -213,6 +213,9 @@ endif if CH347 DRIVERFILES += %D%/ch347.c endif +if CKLINK +DRIVERFILES += %D%/cklink.c +endif DRIVERHEADERS = \ %D%/bitbang.h \ diff --git a/src/jtag/drivers/cklink.c b/src/jtag/drivers/cklink.c new file mode 100644 index 0000000000..efbbd85a44 --- /dev/null +++ b/src/jtag/drivers/cklink.c @@ -0,0 +1,802 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * T-Head CK-Link JTAG adapter driver. * + * * + * Supports the CK-Link Lite V2 wire protocol used by T-Head probes and * + * Bouffalo Lab BL616/BL702 CK-Link clones. USB bulk with a framed * + * command protocol reverse-engineered from T-Head's DebugServer. * + * * + * Copyright (C) 2026 by William Markezana * + * <wil...@gm...> * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <assert.h> + +#include <jtag/adapter.h> +#include <jtag/interface.h> +#include <jtag/commands.h> +#include <helper/binarybuffer.h> +#include <helper/bits.h> +#include <helper/time_support.h> +#include "libusb_helper.h" + +/* USB identification. VID/PID table is extendable via `cklink vid_pid`. */ +#define CKLINK_VID_BOUFFALO 0x42bf +#define CKLINK_VID_THEAD 0x32bf +#define CKLINK_PID_LITE_V2 0xb210 +#define CKLINK_MAX_VID_PIDS 8 + +#define CKLINK_USB_INTERFACE 0 +#define CKLINK_EP_OUT 0x02 +#define CKLINK_EP_IN 0x81 +#define CKLINK_USB_TIMEOUT_MS 1000 +#define CKLINK_USB_BUF_SIZE 2048 + +/* Wire-protocol framing bytes */ +#define CKLINK_FRAME_START 0x68 +#define CKLINK_FRAME_END 0x16 + +/* Response frame layout: start + status + payload + checksum + end */ +#define CKLINK_FRAME_OVERHEAD 4 +#define CKLINK_RESP_PAYLOAD_OFFSET 2 + +/* Opcodes */ +#define CKLINK_OP_SELFREG_WRITE 0x06 +#define CKLINK_OP_SELFREG_READ 0x87 +#define CKLINK_OP_JTAG_BATCH 0x88 + +/* Self-register indices */ +#define CKLINK_SR_CSR 0 /* clock divider + CDI mode */ +#define CKLINK_SR_MTCR_WAIT 1 /* target-comm wait cycles */ +#define CKLINK_SR_JTAG_CONFIG 8 /* JTAG config word */ +#define CKLINK_SELFREG_BYTES 4 + +/* + * Init values replayed from a captured DebugServer session. + * sr0 (CSR): byte 0 = clock divider, byte 3 = CDI mode (0x60=5-wire JTAG, + * 0x61=2-wire cJTAG). The 5->2->5 mode toggle at end of init acts as a + * TAP reset: the wire driver re-initializes on each switch. + * sr1 MTCR_WAIT = 1000 cycles. sr8 JTAG_CONFIG: opaque, known-good. + */ +#define CKLINK_SR0_SETUP_CLK_BYTE 0x17 /* ~2000 kHz */ +#define CKLINK_SR0_RUN_CLK_BYTE 0x12 /* ~2526 kHz, DebugServer default */ +#define CKLINK_SR0_MODE_JTAG 0x60 +#define CKLINK_SR0_MODE_CJTAG 0x61 +#define CKLINK_SR1_INIT_VALUE 0x000003e8 +#define CKLINK_SR8_INIT_VALUE 0x00622250 + +/* freq_kHz = 48000 / (N + 1); cap at DebugServer-validated 0x12. */ +#define CKLINK_CLK_SOURCE_KHZ 48000 +#define CKLINK_CLK_DIV_MIN CKLINK_SR0_RUN_CLK_BYTE +#define CKLINK_CLK_DIV_MAX 0xff + +#define CKLINK_CSR(clk, mode) (((uint32_t)(mode) << 24) | (clk)) + +/* Batch opcode encodes IR/DR bit-counts in single bytes. */ +#define CKLINK_MAX_SCAN_BITS 255 +#define CKLINK_MAX_SCAN_BYTES 32 /* DIV_ROUND_UP(255, 8) */ + +/* Synthesized IR when a DR scan arrives without a cached IR. */ +#define CKLINK_PLACEHOLDER_IR_BITS 5 +#define CKLINK_PLACEHOLDER_IR_VALUE 0x01 + +struct cklink_ctx { + struct libusb_device_handle *usb_dev; + uint8_t tx_buf[CKLINK_USB_BUF_SIZE]; + uint8_t rx_buf[CKLINK_USB_BUF_SIZE]; + uint8_t csr_clk; + uint8_t ir_value[CKLINK_MAX_SCAN_BYTES]; + unsigned int ir_bits; + struct jtag_command *pending_ir_cmd; + uint8_t *scan_tdi; + uint8_t *scan_tdo; + size_t scan_buf_size; + bool long_scan_warned; + bool dropped_ir_warned; +}; + +static struct cklink_ctx *cklink_handle; + +/* VID/PID table, NULL-terminated pairs; extendable via `cklink vid_pid`. */ +static uint16_t cklink_vids[CKLINK_MAX_VID_PIDS + 1] = { + CKLINK_VID_BOUFFALO, + CKLINK_VID_THEAD, +}; +static uint16_t cklink_pids[CKLINK_MAX_VID_PIDS + 1] = { + CKLINK_PID_LITE_V2, + CKLINK_PID_LITE_V2, +}; + +/* Sum-mod-256. */ +static uint8_t cklink_checksum(const uint8_t *buf, int len) +{ + unsigned int sum = 0; + for (int i = 0; i < len; i++) + sum += buf[i]; + return (uint8_t)(sum & 0xff); +} + +/* Send a framed command; NULL rxlen means fire-and-forget (selfreg writes + * are not acknowledged). @p opcode selects the response-checksum rule. */ +static int cklink_usb_xfer(struct cklink_ctx *ck, uint8_t opcode, + int txlen, int *rxlen) +{ + int actual = 0; + int ret = jtag_libusb_bulk_write(ck->usb_dev, CKLINK_EP_OUT, + (char *)ck->tx_buf, txlen, + CKLINK_USB_TIMEOUT_MS, &actual); + if (ret != ERROR_OK || actual != txlen) { + LOG_ERROR("CK-Link bulk write failed (ret=%d, actual=%d/%d)", + ret, actual, txlen); + return ERROR_FAIL; + } + + if (!rxlen) + return ERROR_OK; + + ret = jtag_libusb_bulk_read(ck->usb_dev, CKLINK_EP_IN, + (char *)ck->rx_buf, CKLINK_USB_BUF_SIZE, + CKLINK_USB_TIMEOUT_MS, &actual); + if (ret != ERROR_OK || actual < CKLINK_FRAME_OVERHEAD) { + LOG_ERROR("CK-Link bulk read failed (ret=%d, actual=%d)", + ret, actual); + return ERROR_FAIL; + } + if (ck->rx_buf[0] != CKLINK_FRAME_START) { + LOG_ERROR("CK-Link bad response start byte 0x%02x", + ck->rx_buf[0]); + return ERROR_FAIL; + } + if (ck->rx_buf[actual - 1] != CKLINK_FRAME_END) { + LOG_ERROR("CK-Link bad response end byte 0x%02x", + ck->rx_buf[actual - 1]); + return ERROR_FAIL; + } + /* + * RX checksum is opcode-specific: selfreg reads sum all payload; + * single-entry JTAG batch sums all except the last byte of dr_tdo. + */ + int csum_end = (opcode == CKLINK_OP_JTAG_BATCH) ? actual - 3 + : actual - 2; + uint8_t computed = cklink_checksum(ck->rx_buf, csum_end); + if (computed != ck->rx_buf[actual - 2]) { + LOG_ERROR("CK-Link response checksum mismatch: op=0x%02x stated=0x%02x computed=0x%02x", + opcode, ck->rx_buf[actual - 2], computed); + return ERROR_FAIL; + } + /* Status byte semantics undocumented; log non-zero for traces. */ + if (ck->rx_buf[1] != 0) { + LOG_DEBUG("CK-Link op=0x%02x returned status=0x%02x", + opcode, ck->rx_buf[1]); + } + *rxlen = actual; + return ERROR_OK; +} + +static int cklink_frame_start(struct cklink_ctx *ck, uint8_t opcode) +{ + ck->tx_buf[0] = CKLINK_FRAME_START; + ck->tx_buf[1] = opcode; + return 2; +} + +static int cklink_frame_end(struct cklink_ctx *ck, int pos) +{ + assert(pos + 2 <= CKLINK_USB_BUF_SIZE); + ck->tx_buf[pos] = cklink_checksum(ck->tx_buf, pos); + ck->tx_buf[pos + 1] = CKLINK_FRAME_END; + return pos + 2; +} + +static int cklink_selfreg_write(struct cklink_ctx *ck, uint8_t reg, + const uint8_t *value) +{ + int pos = cklink_frame_start(ck, CKLINK_OP_SELFREG_WRITE); + ck->tx_buf[pos++] = reg; + memcpy(&ck->tx_buf[pos], value, CKLINK_SELFREG_BYTES); + pos += CKLINK_SELFREG_BYTES; + pos = cklink_frame_end(ck, pos); + return cklink_usb_xfer(ck, CKLINK_OP_SELFREG_WRITE, pos, NULL); +} + +static int cklink_selfreg_read(struct cklink_ctx *ck, uint8_t reg, uint8_t *value) +{ + int pos = cklink_frame_start(ck, CKLINK_OP_SELFREG_READ); + ck->tx_buf[pos++] = reg; + pos = cklink_frame_end(ck, pos); + + int rxlen = 0; + int ret = cklink_usb_xfer(ck, CKLINK_OP_SELFREG_READ, pos, &rxlen); + if (ret != ERROR_OK) + return ret; + + const int expected = CKLINK_FRAME_OVERHEAD + CKLINK_SELFREG_BYTES; + if (rxlen < expected) { + LOG_ERROR("CK-Link selfreg read response too short (%d < %d)", + rxlen, expected); + return ERROR_FAIL; + } + memcpy(value, &ck->rx_buf[CKLINK_RESP_PAYLOAD_OFFSET], + CKLINK_SELFREG_BYTES); + return ERROR_OK; +} + +/* Single-entry batch scan. Scans > 255 bits are clamped with a one-time + * warning: chunking across entries breaks Shift-DR continuity, and + * erroring out here breaks OpenOCD's chain probe's -expected-id recovery. */ +static int cklink_jtag_scan(struct cklink_ctx *ck, + unsigned int ir_bits, const uint8_t *ir_tdi, + uint8_t *ir_tdo, + unsigned int dr_bits, const uint8_t *dr_tdi, + uint8_t *dr_tdo) +{ + if ((ir_bits > CKLINK_MAX_SCAN_BITS || dr_bits > CKLINK_MAX_SCAN_BITS) + && !ck->long_scan_warned) { + LOG_WARNING("CK-Link: scan exceeds %u-bit per-entry limit (ir=%u dr=%u); clamping", + CKLINK_MAX_SCAN_BITS, ir_bits, dr_bits); + ck->long_scan_warned = true; + } + if (ir_bits > CKLINK_MAX_SCAN_BITS) + ir_bits = CKLINK_MAX_SCAN_BITS; + if (dr_bits > CKLINK_MAX_SCAN_BITS) + dr_bits = CKLINK_MAX_SCAN_BITS; + + const unsigned int ir_bytes = DIV_ROUND_UP(ir_bits, 8); + const unsigned int dr_bytes = DIV_ROUND_UP(dr_bits, 8); + + int pos = cklink_frame_start(ck, CKLINK_OP_JTAG_BATCH); + ck->tx_buf[pos++] = 0; /* entry_count - 1 */ + ck->tx_buf[pos++] = (uint8_t)ir_bits; + if (ir_tdi) + memcpy(&ck->tx_buf[pos], ir_tdi, ir_bytes); + else + memset(&ck->tx_buf[pos], 0, ir_bytes); + pos += ir_bytes; + ck->tx_buf[pos++] = (uint8_t)dr_bits; + if (dr_tdi) + memcpy(&ck->tx_buf[pos], dr_tdi, dr_bytes); + else + memset(&ck->tx_buf[pos], 0, dr_bytes); + pos += dr_bytes; + pos = cklink_frame_end(ck, pos); + + int rxlen = 0; + int ret = cklink_usb_xfer(ck, CKLINK_OP_JTAG_BATCH, pos, &rxlen); + if (ret != ERROR_OK) + return ret; + + /* Response: start + status + ir_tdo + dr_echo + dr_tdo + csum + end. */ + const unsigned int expected = + CKLINK_FRAME_OVERHEAD + ir_bytes + 1 + dr_bytes; + if ((unsigned int)rxlen < expected) { + LOG_ERROR("CK-Link scan response truncated: got %d, need %u (ir=%u dr=%u)", + rxlen, expected, ir_bits, dr_bits); + return ERROR_FAIL; + } + + if (ir_tdo && ir_bytes) + memcpy(ir_tdo, &ck->rx_buf[CKLINK_RESP_PAYLOAD_OFFSET], ir_bytes); + + const unsigned int dr_tdo_offset = + CKLINK_RESP_PAYLOAD_OFFSET + ir_bytes + 1; + if (dr_tdo) + memcpy(dr_tdo, &ck->rx_buf[dr_tdo_offset], dr_bytes); + + return ERROR_OK; +} + +/* Shift num_bits of idle cycles, chunked to the 255-bit protocol limit. */ +static int cklink_idle_cycles(struct cklink_ctx *ck, unsigned int num_bits) +{ + static const uint8_t zeros[CKLINK_MAX_SCAN_BYTES] = { 0 }; + + while (num_bits > 0) { + unsigned int chunk = num_bits > CKLINK_MAX_SCAN_BITS + ? CKLINK_MAX_SCAN_BITS : num_bits; + int ret = cklink_jtag_scan(ck, 0, NULL, NULL, + chunk, zeros, NULL); + if (ret != ERROR_OK) + return ret; + num_bits -= chunk; + } + return ERROR_OK; +} + +/* Flush a pending IR with a 1-bit dummy DR so its in_value gets populated + * with real captured IR TDO. Called at end of execute_queue so Capture-IR + * validation sees real hardware data. */ +static int cklink_flush_pending_ir(struct cklink_ctx *ck) +{ + if (!ck || !ck->pending_ir_cmd) + return ERROR_OK; + + uint8_t ir_tdo[CKLINK_MAX_SCAN_BYTES] = { 0 }; + uint8_t dummy_dr = 0; + int ret = cklink_jtag_scan(ck, ck->ir_bits, ck->ir_value, ir_tdo, + 1, &dummy_dr, NULL); + if (ret != ERROR_OK) + return ret; + + struct scan_command *scan = ck->pending_ir_cmd->cmd.scan; + unsigned int off = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) { + struct scan_field *f = &scan->fields[i]; + if (f->in_value) { + buf_set_buf(ir_tdo, off, f->in_value, 0, + f->num_bits); + } + off += f->num_bits; + } + ck->pending_ir_cmd = NULL; + /* ir_bits/ir_value stay valid: hardware IR is still what we cached. */ + return ERROR_OK; +} + +static int cklink_execute_scan(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + struct scan_command *scan = cmd->cmd.scan; + + unsigned int total_bits = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) + total_bits += scan->fields[i].num_bits; + + if (total_bits == 0) + return ERROR_OK; + + const unsigned int total_bytes = DIV_ROUND_UP(total_bits, 8); + if (total_bytes > ck->scan_buf_size) { + uint8_t *ntdi = realloc(ck->scan_tdi, total_bytes); + uint8_t *ntdo = realloc(ck->scan_tdo, total_bytes); + if (!ntdi || !ntdo) { + LOG_ERROR("CK-Link: out of memory for %u-bit scan", + total_bits); + /* Partial success is fine; freed in cklink_quit. */ + if (ntdi) + ck->scan_tdi = ntdi; + if (ntdo) + ck->scan_tdo = ntdo; + return ERROR_FAIL; + } + ck->scan_tdi = ntdi; + ck->scan_tdo = ntdo; + ck->scan_buf_size = total_bytes; + } + memset(ck->scan_tdi, 0, total_bytes); + memset(ck->scan_tdo, 0, total_bytes); + + unsigned int bit_offset = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) { + struct scan_field *field = &scan->fields[i]; + if (field->out_value) { + buf_set_buf(field->out_value, 0, ck->scan_tdi, + bit_offset, field->num_bits); + } + bit_offset += field->num_bits; + } + + if (scan->ir_scan) { + /* + * Defer IR until paired with a DR (batch needs both). + * Back-to-back IR drops the first: mid-queue flush would + * cycle Capture-DR/Update-DR on the previous IR's register + * (e.g. DMI), triggering spurious transactions. + */ + if (total_bytes > sizeof(ck->ir_value)) { + LOG_ERROR("CK-Link: IR scan of %u bits exceeds cache (%zu bytes)", + total_bits, sizeof(ck->ir_value)); + return ERROR_JTAG_QUEUE_FAILED; + } + if (ck->pending_ir_cmd) { + if (!ck->dropped_ir_warned) { + LOG_WARNING("CK-Link: back-to-back IR scan dropped pending IR; multi-TAP chains are not supported"); + ck->dropped_ir_warned = true; + } else { + LOG_DEBUG("CK-Link: dropping pending IR (%u bits) before new IR scan", + ck->ir_bits); + } + } + memcpy(ck->ir_value, ck->scan_tdi, total_bytes); + ck->ir_bits = total_bits; + ck->pending_ir_cmd = cmd; + return ERROR_OK; + } + + /* No cached IR yet: inject IDCODE placeholder so chain detection works. */ + const uint8_t placeholder_ir = CKLINK_PLACEHOLDER_IR_VALUE; + const unsigned int eff_ir_bits = ck->ir_bits ? ck->ir_bits + : CKLINK_PLACEHOLDER_IR_BITS; + const uint8_t *eff_ir_value = ck->ir_bits ? ck->ir_value : &placeholder_ir; + if (!ck->ir_bits) + LOG_DEBUG("CK-Link: DR scan with no cached IR; injecting IDCODE placeholder"); + + uint8_t ir_tdo_buf[CKLINK_MAX_SCAN_BYTES] = { 0 }; + int ret = cklink_jtag_scan(ck, eff_ir_bits, eff_ir_value, ir_tdo_buf, + total_bits, ck->scan_tdi, ck->scan_tdo); + if (ret != ERROR_OK) + return ret; + + /* Scatter captured IR TDO back into the deferred IR command's fields. */ + if (ck->pending_ir_cmd) { + struct scan_command *ir_scan = ck->pending_ir_cmd->cmd.scan; + unsigned int ir_off = 0; + for (unsigned int i = 0; i < ir_scan->num_fields; i++) { + struct scan_field *f = &ir_scan->fields[i]; + if (f->in_value) { + buf_set_buf(ir_tdo_buf, ir_off, + f->in_value, 0, f->num_bits); + } + ir_off += f->num_bits; + } + ck->pending_ir_cmd = NULL; + } + + /* + * For clamped scans, fill un-shifted TDO with caller's TDI (models + * "no more TAPs past the limit" - a bare wire). Gives OpenOCD's + * bypass chain-length probe the expected end-of-chain marker. + */ + if (total_bits > CKLINK_MAX_SCAN_BITS) { + buf_set_buf(ck->scan_tdi, CKLINK_MAX_SCAN_BITS, + ck->scan_tdo, CKLINK_MAX_SCAN_BITS, + total_bits - CKLINK_MAX_SCAN_BITS); + } + + bit_offset = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) { + struct scan_field *field = &scan->fields[i]; + if (field->in_value) { + buf_set_buf(ck->scan_tdo, bit_offset, + field->in_value, 0, field->num_bits); + } + bit_offset += field->num_bits; + } + + return ERROR_OK; +} + +static int cklink_write_csr(struct cklink_ctx *ck, uint8_t clk, uint8_t mode) +{ + uint8_t buf[CKLINK_SELFREG_BYTES]; + h_u32_to_le(buf, CKLINK_CSR(clk, mode)); + return cklink_selfreg_write(ck, CKLINK_SR_CSR, buf); +} + +/* khz -> sr0 byte 0 divider, rounded up so we never exceed the request. */ +static uint8_t cklink_khz_to_div(int khz) +{ + if (khz <= 0) + return CKLINK_CLK_DIV_MAX; + int n = ((CKLINK_CLK_SOURCE_KHZ + khz - 1) / khz) - 1; + if (n < CKLINK_CLK_DIV_MIN) + n = CKLINK_CLK_DIV_MIN; + if (n > CKLINK_CLK_DIV_MAX) + n = CKLINK_CLK_DIV_MAX; + return (uint8_t)n; +} + +static int cklink_execute_tlr_reset(struct cklink_ctx *ck) +{ + /* Probe-side reset via 5->2->5 mode toggle; target TAP reset not guaranteed. */ + int ret; + + ret = cklink_write_csr(ck, ck->csr_clk, CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, ck->csr_clk, CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, ck->csr_clk, CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + + ck->ir_bits = 0; + memset(ck->ir_value, 0, sizeof(ck->ir_value)); + ck->pending_ir_cmd = NULL; + tap_set_state(TAP_RESET); + return ERROR_OK; +} + +static int cklink_execute_runtest(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + return cklink_idle_cycles(ck, cmd->cmd.runtest->num_cycles); +} + +static int cklink_execute_stableclocks(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + /* TMS=0 shifts only hold state in RTI; other stable states would advance. */ + return cklink_idle_cycles(ck, cmd->cmd.stableclocks->num_cycles); +} + +static int cklink_execute_tms(struct jtag_command *cmd) +{ + /* No TMS-sequence opcode: honoring JTAG_TMS is impossible. */ + LOG_ERROR("CK-Link: JTAG_TMS (%u bits) is not supported by this probe", + cmd->cmd.tms->num_bits); + return ERROR_JTAG_NOT_IMPLEMENTED; +} + +static int cklink_execute_reset(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + /* Only TRST is meaningful here: we have no separate SRST control. */ + if (cmd->cmd.reset->trst) + return cklink_execute_tlr_reset(ck); + return ERROR_OK; +} + +static int cklink_execute_queue(struct jtag_command *cmd_queue) +{ + struct cklink_ctx *ck = cklink_handle; + if (!ck) + return ERROR_JTAG_INIT_FAILED; + + for (struct jtag_command *cmd = cmd_queue; cmd; cmd = cmd->next) { + int ret; + + switch (cmd->type) { + case JTAG_SCAN: + ret = cklink_execute_scan(ck, cmd); + break; + case JTAG_TLR_RESET: + ret = cklink_execute_tlr_reset(ck); + break; + case JTAG_RUNTEST: + ret = cklink_execute_runtest(ck, cmd); + break; + case JTAG_RESET: + ret = cklink_execute_reset(ck, cmd); + break; + case JTAG_PATHMOVE: + /* No TMS-sequence opcode: honoring PATHMOVE is impossible. */ + LOG_ERROR("CK-Link: JTAG_PATHMOVE is not supported by this probe"); + ret = ERROR_JTAG_NOT_IMPLEMENTED; + break; + case JTAG_STABLECLOCKS: + ret = cklink_execute_stableclocks(ck, cmd); + break; + case JTAG_TMS: + ret = cklink_execute_tms(cmd); + break; + case JTAG_SLEEP: + jtag_sleep(cmd->cmd.sleep->us); + ret = ERROR_OK; + break; + default: + LOG_ERROR("CK-Link: unsupported JTAG command %d", + cmd->type); + return ERROR_JTAG_QUEUE_FAILED; + } + if (ret != ERROR_OK) + return ret; + } + /* Flush so any un-paired IR's in_value is populated before OpenOCD reads. */ + return cklink_flush_pending_ir(ck); +} + +static int cklink_probe_init(struct cklink_ctx *ck) +{ + uint8_t sr1[CKLINK_SELFREG_BYTES]; + uint8_t sr8[CKLINK_SELFREG_BYTES]; + uint8_t readback[CKLINK_SELFREG_BYTES]; + int ret; + + h_u32_to_le(sr1, CKLINK_SR1_INIT_VALUE); + h_u32_to_le(sr8, CKLINK_SR8_INIT_VALUE); + + /* DebugServer init sequence, replayed verbatim. */ + ret = cklink_write_csr(ck, CKLINK_SR0_SETUP_CLK_BYTE, + CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_selfreg_write(ck, CKLINK_SR_MTCR_WAIT, sr1); + if (ret != ERROR_OK) + return ret; + ret = cklink_selfreg_write(ck, CKLINK_SR_JTAG_CONFIG, sr8); + if (ret != ERROR_OK) + return ret; + + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + + /* 5->2->5 mode toggle: effective TAP reset. */ + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + + ret = cklink_selfreg_read(ck, CKLINK_SR_CSR, readback); + if (ret != ERROR_OK) + return ret; + if (readback[3] != CKLINK_SR0_MODE_JTAG) { + LOG_WARNING("CK-Link: sr0 mode byte is 0x%02x, expected 0x%02x (5-wire JTAG)", + readback[3], CKLINK_SR0_MODE_JTAG); + } + ck->csr_clk = CKLINK_SR0_RUN_CLK_BYTE; + + /* Pre-load IR = IDCODE; 1-bit DR is the minimum the batch opcode accepts. */ + const uint8_t idcode_ir = CKLINK_PLACEHOLDER_IR_VALUE; + const uint8_t dummy_dr = 0; + return cklink_jtag_scan(ck, CKLINK_PLACEHOLDER_IR_BITS, &idcode_ir, NULL, + 1, &dummy_dr, NULL); +} + +static int cklink_init(void) +{ + struct cklink_ctx *ck = calloc(1, sizeof(*ck)); + if (!ck) { + LOG_ERROR("CK-Link: out of memory"); + return ERROR_JTAG_INIT_FAILED; + } + + const char *serial = adapter_get_required_serial(); + if (jtag_libusb_open(cklink_vids, cklink_pids, serial, + &ck->usb_dev, NULL) != ERROR_OK) { + LOG_ERROR("CK-Link probe not found"); + free(ck); + return ERROR_JTAG_INIT_FAILED; + } + + libusb_set_auto_detach_kernel_driver(ck->usb_dev, 1); + + int claim = libusb_claim_interface(ck->usb_dev, CKLINK_USB_INTERFACE); + if (claim != 0) { + LOG_ERROR("CK-Link: failed to claim interface %d: %s", + CKLINK_USB_INTERFACE, libusb_error_name(claim)); + jtag_libusb_close(ck->usb_dev); + free(ck); + return ERROR_JTAG_INIT_FAILED; + } + + if (cklink_probe_init(ck) != ERROR_OK) { + LOG_ERROR("CK-Link: probe initialization failed"); + libusb_release_interface(ck->usb_dev, CKLINK_USB_INTERFACE); + jtag_libusb_close(ck->usb_dev); + free(ck); + return ERROR_JTAG_INIT_FAILED; + } + + cklink_handle = ck; + tap_set_state(TAP_RESET); + LOG_INFO("CK-Link Lite V2 initialized (5-wire JTAG)"); + return ERROR_OK; +} + +static int cklink_quit(void) +{ + if (!cklink_handle) + return ERROR_OK; + + libusb_release_interface(cklink_handle->usb_dev, + CKLINK_USB_INTERFACE); + jtag_libusb_close(cklink_handle->usb_dev); + free(cklink_handle->scan_tdi); + free(cklink_handle->scan_tdo); + free(cklink_handle); + cklink_handle = NULL; + return ERROR_OK; +} + +static int cklink_speed(int speed) +{ + struct cklink_ctx *ck = cklink_handle; + if (!ck) + return ERROR_OK; /* called before init */ + + uint8_t div = cklink_khz_to_div(speed); + if (div == ck->csr_clk) + return ERROR_OK; + int ret = cklink_write_csr(ck, div, CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + ck->csr_clk = div; + int actual = CKLINK_CLK_SOURCE_KHZ / (div + 1); + LOG_DEBUG("CK-Link: adapter speed: requested %d kHz, programmed %d kHz (div=0x%02x)", + speed, actual, div); + return ERROR_OK; +} + +static int cklink_khz(int khz, int *jtag_speed) +{ + if (khz == 0) { + LOG_ERROR("CK-Link: adaptive clocking (RTCK) is not supported"); + return ERROR_JTAG_NOT_IMPLEMENTED; + } + uint8_t div = cklink_khz_to_div(khz); + int achievable = CKLINK_CLK_SOURCE_KHZ / (div + 1); + if (achievable != khz) { + static int last_clamp_khz; + if (khz != last_clamp_khz) { + LOG_WARNING("CK-Link: requested %d kHz clamped to %d kHz (div=0x%02x)", + khz, achievable, div); + last_clamp_khz = khz; + } + } + *jtag_speed = achievable; + return ERROR_OK; +} + +static int cklink_speed_div(int speed, int *khz) +{ + *khz = speed; + return ERROR_OK; +} + +COMMAND_HANDLER(cklink_handle_vid_pid_command) +{ + if (CMD_ARGC < 2 || CMD_ARGC % 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + unsigned int pairs = CMD_ARGC / 2; + if (pairs > CKLINK_MAX_VID_PIDS) { + LOG_ERROR("CK-Link: too many vid/pid pairs (max %d)", + CKLINK_MAX_VID_PIDS); + return ERROR_COMMAND_SYNTAX_ERROR; + } + for (unsigned int i = 0; i < pairs; i++) { + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2 * i], cklink_vids[i]); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2 * i + 1], cklink_pids[i]); + if (cklink_vids[i] == 0 || cklink_pids[i] == 0) { + LOG_ERROR("CK-Link: vid/pid must be non-zero (pair %u)", i); + return ERROR_COMMAND_SYNTAX_ERROR; + } + } + cklink_vids[pairs] = 0; + cklink_pids[pairs] = 0; + return ERROR_OK; +} + +static const struct command_registration cklink_subcommand_handlers[] = { + { + .name = "vid_pid", + .handler = &cklink_handle_vid_pid_command, + .mode = COMMAND_CONFIG, + .help = "VID/PID pairs of CK-Link probes to match (replaces defaults)", + .usage = "(vid pid)+", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration cklink_command_handlers[] = { + { + .name = "cklink", + .mode = COMMAND_ANY, + .help = "perform cklink management", + .chain = cklink_subcommand_handlers, + .usage = "<subcommand> [args...]", + }, + COMMAND_REGISTRATION_DONE +}; + +static struct jtag_interface cklink_jtag_interface = { + .execute_queue = cklink_execute_queue, +}; + +struct adapter_driver cklink_adapter_driver = { + .name = "cklink", + .transport_ids = TRANSPORT_JTAG, + .transport_preferred_id = TRANSPORT_JTAG, + .commands = cklink_command_handlers, + + .init = cklink_init, + .quit = cklink_quit, + .speed = cklink_speed, + .khz = cklink_khz, + .speed_div = cklink_speed_div, + + .jtag_ops = &cklink_jtag_interface, +}; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 51cbf9ac0d..5c6c8eea93 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -380,6 +380,7 @@ extern struct adapter_driver at91rm9200_adapter_driver; extern struct adapter_driver bcm2835gpio_adapter_driver; extern struct adapter_driver buspirate_adapter_driver; extern struct adapter_driver ch347_adapter_driver; +extern struct adapter_driver cklink_adapter_driver; extern struct adapter_driver cmsis_dap_adapter_driver; extern struct adapter_driver dmem_dap_adapter_driver; extern struct adapter_driver dummy_adapter_driver; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index caf5ace999..60c7364c64 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -62,6 +62,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_CH347 == 1 &ch347_adapter_driver, #endif +#if BUILD_CKLINK == 1 + &cklink_adapter_driver, +#endif #if BUILD_CMSIS_DAP_USB == 1 || BUILD_CMSIS_DAP_HID == 1 || BUILD_CMSIS_DAP_TCP == 1 &cmsis_dap_adapter_driver, #endif diff --git a/tcl/interface/cklink.cfg b/tcl/interface/cklink.cfg new file mode 100644 index 0000000000..fb017aa056 --- /dev/null +++ b/tcl/interface/cklink.cfg @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# T-Head CK-Link JTAG adapter (including Bouffalo BL616/BL702 clones) +# + +adapter driver cklink -- |
|
From: <ge...@op...> - 2026-04-23 12:27:58
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9585 -- gerrit commit cc15f48a37609e3d23b144f04a6d7a4a9de09057 Author: Marc Schink <de...@za...> Date: Wed Apr 22 17:09:02 2026 +0200 adapter/stlink: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'st-link vid_pid' command for backwards compatibility, but mark it as deprecated. Checkpatch-ignore: LONG_LINE Change-Id: Ibd56adda044845148f0b130dcaf5e98b412be3be Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index ee97868508..7dcb0be176 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3410,10 +3410,6 @@ ST-LINK server software module}. @emph{Note:} ST-Link TCP server does not support the SWIM transport. @end deffn -@deffn {Config Command} {st-link vid_pid} [vid pid]+ -Pairs of vendor IDs and product IDs of the device. -@end deffn - @deffn {Command} {st-link cmd} rx_n (tx_byte)+ Sends an arbitrary command composed by the sequence of bytes @var{tx_byte} and receives @var{rx_n} bytes. diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index b4d21100cc..bac9c26cb5 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3406,7 +3406,7 @@ static int stlink_usb_usb_open(void *handle, struct hl_interface_param *param) in order to become operational. */ do { - if (jtag_libusb_open(param->vid, param->pid, NULL, + if (jtag_libusb_open(adapter_usb_get_vids(), adapter_usb_get_pids(), NULL, &h->usb_backend_priv.fd, stlink_usb_get_alternate_serial) != ERROR_OK) { LOG_ERROR("open failed"); return ERROR_FAIL; @@ -3740,9 +3740,9 @@ static int stlink_open(struct hl_interface_param *param, enum stlink_mode mode, h->st_mode = mode; - for (unsigned int i = 0; param->vid[i]; i++) { + for (unsigned int i = 0; adapter_usb_get_vids()[i]; i++) { LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", - h->st_mode, param->vid[i], param->pid[i], + h->st_mode, adapter_usb_get_vids()[i], adapter_usb_get_pids()[i], adapter_get_required_serial() ? adapter_get_required_serial() : ""); } @@ -4984,31 +4984,6 @@ static int stlink_dap_trace_read(uint8_t *buf, size_t *size) return stlink_usb_trace_read(stlink_dap_handle, buf, size); } -/** */ -COMMAND_HANDLER(stlink_dap_vid_pid) -{ - unsigned int i, max_usb_ids = HLA_MAX_USB_IDS; - - if (CMD_ARGC > max_usb_ids * 2) { - LOG_WARNING("ignoring extra IDs in vid_pid " - "(maximum is %d pairs)", max_usb_ids); - CMD_ARGC = max_usb_ids * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete vid_pid configuration directive"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], stlink_dap_param.vid[i / 2]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], stlink_dap_param.pid[i / 2]); - } - - /* null termination */ - stlink_dap_param.vid[i / 2] = stlink_dap_param.pid[i / 2] = 0; - - return ERROR_OK; -} - /** */ COMMAND_HANDLER(stlink_dap_backend_command) { @@ -5074,13 +5049,6 @@ COMMAND_HANDLER(stlink_dap_cmd_command) /** */ static const struct command_registration stlink_dap_subcommand_handlers[] = { - { - .name = "vid_pid", - .handler = stlink_dap_vid_pid, - .mode = COMMAND_CONFIG, - .help = "USB VID and PID of the adapter", - .usage = "(vid pid)+", - }, { .name = "backend", .handler = &stlink_dap_backend_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index f24e57ab06..441f2cccb1 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -1183,6 +1183,12 @@ proc "hla_stlink_backend" {args} { eval hla stlink_backend $args } +lappend _telnet_autocomplete_skip "st-link vid_pid" +proc "st-link vid_pid" {args} { + echo "DEPRECATED! use 'adapter usb vid_pid', not 'st-link vid_pid'" + eval adapter usb vid_pid $args +} + lappend _telnet_autocomplete_skip "kitprog_init_acquire_psoc" proc "kitprog_init_acquire_psoc" {} { echo "DEPRECATED! use 'kitprog init_acquire_psoc', not 'kitprog_init_acquire_psoc'" diff --git a/tcl/interface/stlink.cfg b/tcl/interface/stlink.cfg index 48c5656615..2cea18f20a 100644 --- a/tcl/interface/stlink.cfg +++ b/tcl/interface/stlink.cfg @@ -17,7 +17,7 @@ if { [adapter name] == "hla" } { } adapter driver st-link -st-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 +adapter usb vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757 # transport select jtag # transport select swd -- |
|
From: <ge...@op...> - 2026-04-23 12:27:57
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9584 -- gerrit commit cf53fbd49d8d166917bf5e0ea6ed78fac92b08b6 Author: Marc Schink <de...@za...> Date: Wed Apr 22 17:08:20 2026 +0200 adapter: Implement USB VID/PID parsing Currently, eight adapter drivers each implement their own USB VID/PID parsing, leading to duplicated code. Implement VID/PID parsing in the adapter core, similar to how device serials are handled. Driver specific changes will follow in a separate patch series. Change-Id: I314915f79874f9d7becba0d4094efcd2c694f0f0 Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index a21a3e4bda..ee97868508 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2496,6 +2496,14 @@ mapping may not support all of the listed options. Returns the name of the debug adapter driver being used. @end deffn +@deffn {Config Command} {adapter usb vid_pid} [vid pid]+ +Specifies the USB vendor and product IDs of the adapter to use. +Currently, up to 16 [@var{vid}, @var{pid}] pairs may be given, e.g. +@example +adapter usb vid_pid 0xc251 0xf001 0x0d28 0x0204 +@end example +@end deffn + @deffn {Config Command} {adapter usb location} [<bus>-<port>[.<port>]...] Displays or specifies the physical USB port of the adapter to use. The path roots at @var{bus} and walks down the physical ports, with each diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 7bf049cd86..a023438528 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -34,12 +34,17 @@ enum adapter_clk_mode { #define DEFAULT_CLOCK_SPEED_KHZ 100U +#define MAX_USB_IDS 16 + /** * Adapter configuration */ static struct { bool adapter_initialized; char *usb_location; + // vid = pid = 0 marks the end of the list. + uint16_t usb_vids[MAX_USB_IDS + 1]; + uint16_t usb_pids[MAX_USB_IDS + 1]; char *serial; enum adapter_clk_mode clock_mode; int speed_khz; @@ -325,6 +330,16 @@ static void adapter_usb_set_location(const char *location) } #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ +const uint16_t *adapter_usb_get_vids(void) +{ + return adapter_config.usb_vids; +} + +const uint16_t *adapter_usb_get_pids(void) +{ + return adapter_config.usb_pids; +} + const char *adapter_usb_get_location(void) { return adapter_config.usb_location; @@ -1104,7 +1119,38 @@ COMMAND_HANDLER(handle_usb_location_command) } #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ +COMMAND_HANDLER(handle_usb_vid_pid_command) +{ + if (MAX_USB_IDS * 2 < CMD_ARGC) { + LOG_WARNING("ignoring extra IDs in vid_pid " + "(maximum is %d pairs)", MAX_USB_IDS); + CMD_ARGC = MAX_USB_IDS * 2; + } + if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { + LOG_WARNING("incomplete vid_pid configuration directive"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + unsigned int i; + for (i = 0; i < CMD_ARGC; i += 2) { + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], adapter_config.usb_vids[i / 2]); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], adapter_config.usb_pids[i / 2]); + } + + /* null termination */ + adapter_config.usb_vids[i / 2] = 0; + adapter_config.usb_pids[i / 2] = 0; + + return ERROR_OK; +} + static const struct command_registration adapter_usb_command_handlers[] = { + { + .name = "vid_pid", + .handler = &handle_usb_vid_pid_command, + .mode = COMMAND_CONFIG, + .help = "display or set the USB VID and PID of the USB device", + .usage = "(vid pid)*", + }, #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS { .name = "location", diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index 6e957cbdc0..4254ae96dc 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -95,6 +95,11 @@ const char *adapter_usb_get_location(void); /** @returns true if USB location string is "<dev_bus>-<port_path[0]>[.<port_path[1]>[...]]" */ bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len); +/** @returns USB VIDs set with command 'adapter usb vid_pid' */ +const uint16_t *adapter_usb_get_vids(void); +/** @returns USB PIDs set with command 'adapter usb vid_pid' */ +const uint16_t *adapter_usb_get_pids(void); + /** @returns The current adapter speed setting. */ int adapter_get_speed(int *speed); -- |
|
From: Tomas V. <to...@us...> - 2026-04-23 09:19:12
|
--- **[tickets:#470] adapter speed changes in target events fails with a fixed speed adapter** **Status:** new **Milestone:** 0.12.0 **Created:** Thu Apr 23, 2026 09:19 AM UTC by Tomas Vanek **Last Updated:** Thu Apr 23, 2026 09:19 AM UTC **Owner:** nobody If we use a fixed speed adapter (e.g. linuxgpiod) `adapter speed` command in the configuration phase is silently ignored. On the other hand `adapter speed` after `init` fails with `Translation from khz to adapter speed not implemented` Since merging 5049: target: use LOG_USER to print errors in events | https://review.openocd.org/c/openocd/+/5049 `adapter speed` used in an event (typically `reset-start` and `reset-init`) logs this: ``` > reset halt Translation from khz to adapter speed not implemented [stm32u3x.cpu] Execution of event reset-start failed: /home/vanekt/o/tcl//target/stm32x5x_common.cfg:125: Error: Traceback (most recent call last): File "embedded:startup.tcl", line 1471, in ocd_process_reset ocd_process_reset_inner halt File "/home/vanekt/o/tcl//target/stm32x5x_common.cfg", line 125, in ocd_process_reset_inner {adapter speed} 480 ``` IMO OpenOCD should accept a fixed speed adapter without making such noise. Moreover if the event contains some other Tcl commands after `adapter speed` they don't get executed. Possible solutions: - use `catch` with `adapter speed` in all event handlers. Con: more than 30 occurrences. - modify adapter.c code not to return error in case of a fixed speed adapter used --- Sent from sourceforge.net because ope...@li... is subscribed to https://sourceforge.net/p/openocd/tickets/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/openocd/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |
|
From: Stefan B. <ste...@us...> - 2026-04-23 09:06:14
|
--- **[tickets:#469] Fix build with GCC 16.x** **Status:** new **Milestone:** 0.12.0 **Created:** Thu Apr 23, 2026 09:06 AM UTC by Stefan Becker **Last Updated:** Thu Apr 23, 2026 09:06 AM UTC **Owner:** nobody **Attachments:** - [0001-build-fix-build-with-GCC-16.x.patch](https://sourceforge.net/p/openocd/tickets/469/attachment/0001-build-fix-build-with-GCC-16.x.patch) (3.8 kB; text/x-patch) GCC 16.x has stricter settings, e.g. `strchr()` on `const char` buffer can only be assigned to `const char` pointer. Attached git patch with the fixes. Tested build on Fedora 44. --- Sent from sourceforge.net because ope...@li... is subscribed to https://sourceforge.net/p/openocd/tickets/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/openocd/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |
|
From: <ge...@op...> - 2026-04-22 06:26:45
|
This is an automated email from Gerrit. "Sameer Srivastava <s-s...@ti...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9527 -- gerrit commit 99e9a4a6b32116f3ce9331b8e066a183d7d6d537 Author: Sameer Srivastava <s-s...@ti...> Date: Sun Mar 8 12:15:13 2026 +0530 src: flash: nor: added am13e230x flash driver Flashing uses the am13e230x flash loader that runs from SRAM, matching the CC26xx pattern. The algorithm is loaded into SRAM and started via target_start_algorithm. OpenOCD streams sector data into two ping-pong buffers; the algorithm erases each sector and programs it using direct FCTL register access. Signed-off-by: Sameer Srivastava <s-s...@ti...> Change-Id: Ifb910a545146514574fb4efecc3ad5aec38e2576 diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 5c4737f7ac..e2b72dd2b4 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -11,6 +11,7 @@ noinst_LTLIBRARIES += %D%/libocdflashnor.la NOR_DRIVERS = \ %D%/aduc702x.c \ %D%/aducm360.c \ + %D%/am13e230x.c \ %D%/ambiqmicro.c \ %D%/artery.c \ %D%/at91sam4.c \ diff --git a/src/flash/nor/am13e230x.c b/src/flash/nor/am13e230x.c new file mode 100644 index 0000000000..8f9d5632fc --- /dev/null +++ b/src/flash/nor/am13e230x.c @@ -0,0 +1,713 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + * + * NOR flash driver for AM13E230X class of uC from Texas Instruments. + * + * Erase uses direct register writes via the debug probe. + * Write uses an on-device algorithm loaded into SRAM (see + * contrib/loaders/flash/am13e230x/ and am13e230x.h). + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "am13e230x.h" +#include <helper/binarybuffer.h> +#include <helper/bits.h> +#include <helper/time_support.h> +#include <target/algorithm.h> +#include <target/armv7m.h> + +/* Region memory map */ +#define AM13_FLASH_BASE_MAIN 0x00000000 +#define AM13_FLASH_BASE_NONMAIN 0x60100000 +#define AM13_NONMAIN_SIZE_PER_BANK 0x1000 + +/* Factory region registers */ +#define AM13_FACTORYREGION 0x60111000 +#define AM13_TRACEID (AM13_FACTORYREGION + 0x000) +#define AM13_DID (AM13_FACTORYREGION + 0x004) +#define AM13_SRAMFLASH (AM13_FACTORYREGION + 0x01C) + +/* Flash controller (NVMNW) registers */ +#define FLASH_CONTROL_BASE 0x40042000 +#define FCTL_REG_CMDEXEC (FLASH_CONTROL_BASE + 0x1100) +#define FCTL_REG_CMDTYPE (FLASH_CONTROL_BASE + 0x1104) +#define FCTL_REG_CMDADDR (FLASH_CONTROL_BASE + 0x1120) +#define FCTL_REG_CMDBYTEN (FLASH_CONTROL_BASE + 0x1124) +#define FCTL_REG_CMDDATAINDEX (FLASH_CONTROL_BASE + 0x112C) +#define FCTL_REG_CMDDATA0 (FLASH_CONTROL_BASE + 0x1130) +#define FCTL_REG_CMDWEPROTA (FLASH_CONTROL_BASE + 0x11D0) +#define FCTL_REG_CMDWEPROTB (FLASH_CONTROL_BASE + 0x11D4) +#define FCTL_REG_CMDWEPROTNM (FLASH_CONTROL_BASE + 0x1210) +#define FCTL_REG_STATCMD (FLASH_CONTROL_BASE + 0x13D0) + +/* GSC flash semaphore registers */ +#define GSC_BASE 0x40046000 +#define GSC_REG_FPC_FLSEMREQ (GSC_BASE + 0x1800) +#define GSC_REG_FPC_FLSEMCLR (GSC_BASE + 0x1804) + +/* STATCMD bits */ +#define FCTL_STATCMD_CMDDONE 0x00000001 +#define FCTL_STATCMD_CMDPASS 0x00000002 +#define FCTL_STATCMD_CMDINPROGRESS 0x00000004 + +/* CMDEXEC / CMDTYPE constants */ +#define FCTL_CMDEXEC_EXECUTE 0x00000001 +#define FCTL_CMDTYPE_PROGRAM 0x00000001 +#define FCTL_CMDTYPE_ERASE 0x00000002 +#define FCTL_CMDTYPE_CLEARSTATUS 0x00000005 +#define FCTL_CMDTYPE_SIZE_ONEWORD 0x00000000 +#define FCTL_CMDTYPE_SIZE_SECTOR 0x00000040 + +/* 128-bit program with hardware ECC generation (matches SDK PROGRAM_128_WITH_ECC) */ +#define AM13_PROGRAM_128_BYTEN 0x0003FFFF + +#define AM13_FLASH_WORD_SIZE 16 + +#define AM13_FLASH_TIMEOUT_MS 8000 +#define AM13_SECTOR_SIZE_BYTES 0x800 +#define TI_MANUFACTURER_ID 0x17 + +/* Flash loader algorithm binary */ +static const uint8_t am13_algo[] = { +#include "../../../contrib/loaders/flash/am13e230x/am13e230x_algo.inc" +}; + +struct am13_flash_bank { + uint32_t did; + uint32_t traceid; + unsigned int main_flash_size_kb; + unsigned int main_flash_num_banks; + unsigned int sram_size_kb; + unsigned int sector_size; + + /* Algorithm state */ + struct working_area *working_area; + struct armv7m_algorithm armv7m_info; +}; + +static int am13_auto_probe(struct flash_bank *bank); + +/* + * GSC flash semaphore must be held before any flash operation. + * The debug probe and the CPU have separate ownership tracking + * (FLSEMSTAT.DBGACC), so the erase path (debug probe) and the + * write path (on-device algorithm) each acquire it independently. + */ + +static void am13_request_gsc_semaphore(struct flash_bank *bank) +{ + target_write_u32(bank->target, GSC_REG_FPC_FLSEMREQ, 1); +} + +static void am13_clear_gsc_semaphore(struct flash_bank *bank) +{ + target_write_u32(bank->target, GSC_REG_FPC_FLSEMCLR, 1); +} + +/* ---------- Flash controller helpers (erase path only) ---------- */ + +static const struct { + unsigned char bit; + const char *name; +} am13_fctl_errors[] = { + { 2, "CMDINPROGRESS" }, + { 4, "FAILWEPROT" }, + { 5, "FAILVERIFY" }, + { 6, "FAILILLADDR" }, + { 7, "FAILMODE" }, + { 12, "FAILMISC" }, +}; + +static const char *am13_fctl_strerror(uint32_t status) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(am13_fctl_errors); i++) { + if (status & BIT(am13_fctl_errors[i].bit)) + return am13_fctl_errors[i].name; + } + return "FAILUNKNOWN"; +} + +static int am13_fctl_wait_done(struct flash_bank *bank) +{ + struct target *target = bank->target; + uint32_t status = 0; + int64_t start_ms = timeval_ms(); + + while ((status & FCTL_STATCMD_CMDDONE) == 0) { + int retval = target_read_u32(target, FCTL_REG_STATCMD, &status); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() - start_ms > AM13_FLASH_TIMEOUT_MS) + break; + keep_alive(); + } + + if ((status & FCTL_STATCMD_CMDPASS) == 0) { + LOG_ERROR("Flash command failed: %s", am13_fctl_strerror(status)); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static int am13_fctl_clear_status(struct flash_bank *bank) +{ + struct target *target = bank->target; + uint32_t status; + int64_t start_ms; + int retval; + + retval = target_write_u32(target, FCTL_REG_CMDTYPE, FCTL_CMDTYPE_CLEARSTATUS); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_EXECUTE); + if (retval != ERROR_OK) + return retval; + + start_ms = timeval_ms(); + do { + retval = target_read_u32(target, FCTL_REG_STATCMD, &status); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() - start_ms > AM13_FLASH_TIMEOUT_MS) { + LOG_ERROR("Timeout waiting for clear status"); + return ERROR_FAIL; + } + keep_alive(); + } while (status & FCTL_STATCMD_CMDINPROGRESS); + + return ERROR_OK; +} + +static int am13_fctl_unprotect(struct flash_bank *bank) +{ + struct target *target = bank->target; + int retval; + + switch (bank->base) { + case AM13_FLASH_BASE_MAIN: + retval = target_write_u32(target, FCTL_REG_CMDWEPROTA, 0); + if (retval != ERROR_OK) + return retval; + return target_write_u32(target, FCTL_REG_CMDWEPROTB, 0); + case AM13_FLASH_BASE_NONMAIN: + return target_write_u32(target, FCTL_REG_CMDWEPROTNM, 0); + default: + return ERROR_FLASH_BANK_INVALID; + } +} + +static int am13_fctl_sector_erase(struct flash_bank *bank, uint32_t addr) +{ + struct target *target = bank->target; + int retval; + + retval = am13_fctl_clear_status(bank); + if (retval != ERROR_OK) + return retval; + + retval = am13_fctl_unprotect(bank); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDTYPE, + FCTL_CMDTYPE_ERASE | FCTL_CMDTYPE_SIZE_SECTOR); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDADDR, addr); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_EXECUTE); + if (retval != ERROR_OK) + return retval; + + return am13_fctl_wait_done(bank); +} + +/* ---------- Flash driver callbacks ---------- */ + +FLASH_BANK_COMMAND_HANDLER(am13_flash_bank_command) +{ + switch (bank->base) { + case AM13_FLASH_BASE_MAIN: + case AM13_FLASH_BASE_NONMAIN: + break; + default: + LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); + return ERROR_FAIL; + } + + struct am13_flash_bank *am13_info = calloc(1, sizeof(*am13_info)); + if (!am13_info) + return ERROR_FAIL; + + bank->driver_priv = am13_info; + am13_info->sector_size = AM13_SECTOR_SIZE_BYTES; + + return ERROR_OK; +} + +static int am13_protect_check(struct flash_bank *bank) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + /* Protection resets after every operation; report as unprotected */ + for (unsigned int i = 0; i < bank->num_sectors; i++) + bank->sectors[i].is_protected = 0; + + return ERROR_OK; +} + +static int am13_erase(struct flash_bank *bank, unsigned int first, + unsigned int last) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + int retval; + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + am13_request_gsc_semaphore(bank); + + for (unsigned int s = first; s <= last; s++) { + uint32_t addr; + + if (bank->base == AM13_FLASH_BASE_NONMAIN) + addr = AM13_FLASH_BASE_NONMAIN + s * am13_info->sector_size; + else + addr = s * am13_info->sector_size; + + retval = am13_fctl_sector_erase(bank, addr); + if (retval != ERROR_OK) { + LOG_ERROR("Sector erase failed at 0x%08" PRIx32, addr); + am13_clear_gsc_semaphore(bank); + return retval; + } + } + + am13_clear_gsc_semaphore(bank); + return ERROR_OK; +} + +/* ---------- Direct write fallback (via debug probe) ---------- */ + +/* + * Word-by-word flash write using direct register access from the debug + * probe. Slower than the on-device algorithm but does not require SRAM, + * so it works as a fallback when the algorithm cannot be loaded (e.g., + * SRAM is needed by a RAM-resident application). + */ +static int am13_write_direct(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + uint32_t addr = bank->base + offset; + int retval; + + am13_request_gsc_semaphore(bank); + + while (count > 0) { + uint32_t n = MIN(count, AM13_FLASH_WORD_SIZE); + uint8_t word[AM13_FLASH_WORD_SIZE]; + + /* Pad partial words with 0xFF */ + memset(word, 0xFF, sizeof(word)); + memcpy(word, buffer, n); + + /* Clear status + unprotect before every word (per SDK) */ + retval = am13_fctl_clear_status(bank); + if (retval != ERROR_OK) + break; + + retval = am13_fctl_unprotect(bank); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDTYPE, + FCTL_CMDTYPE_PROGRAM | FCTL_CMDTYPE_SIZE_ONEWORD); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDBYTEN, + AM13_PROGRAM_128_BYTEN); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDADDR, + addr & 0xFFFFFFF0); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDDATAINDEX, + (addr >> 4) & 3); + if (retval != ERROR_OK) + break; + + retval = target_write_buffer(target, FCTL_REG_CMDDATA0, + AM13_FLASH_WORD_SIZE, word); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDEXEC, + FCTL_CMDEXEC_EXECUTE); + if (retval != ERROR_OK) + break; + + retval = am13_fctl_wait_done(bank); + if (retval != ERROR_OK) + break; + + addr += n; + buffer += n; + count -= n; + } + + am13_clear_gsc_semaphore(bank); + return retval; +} + +/* ---------- Flash loader algorithm ---------- */ + +static int am13_algo_init(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + int retval; + + retval = am13_auto_probe(bank); + if (retval != ERROR_OK) + return retval; + + /* Allocate SRAM for algorithm + buffers */ + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + + retval = target_alloc_working_area(target, AM13_ALGO_WORKING_SIZE, + &am13_info->working_area); + if (retval != ERROR_OK) { + LOG_ERROR("AM13: insufficient SRAM for flash loader (%u bytes)", + AM13_ALGO_WORKING_SIZE); + return retval; + } + + if (am13_info->working_area->address != AM13_ALGO_BASE) { + LOG_ERROR("AM13: working area at wrong address"); + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + retval = target_write_buffer(target, AM13_ALGO_BASE, + sizeof(am13_algo), am13_algo); + if (retval != ERROR_OK) { + LOG_ERROR("AM13: failed to load flash algorithm"); + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + return retval; + } + + /* + * Release any debug-held GSC semaphore so the algorithm (CPU) + * can acquire it — the flash controller tracks ownership via + * FLSEMSTAT.DBGACC and rejects mismatched access. + */ + am13_clear_gsc_semaphore(bank); + + /* Disable NVIC — stale Zephyr ISRs would fault on overwritten SRAM */ + for (uint32_t icer = 0xE000E180; icer <= 0xE000E19C; icer += 4) + target_write_u32(target, icer, 0xFFFFFFFF); + + /* Disable MPU — previous app may restrict peripheral access */ + target_write_u32(target, 0xE000ED94, 0x00000000); + + am13_info->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + am13_info->armv7m_info.core_mode = ARM_MODE_THREAD; + + /* + * Force privileged Thread mode via reg_param. OpenOCD's + * armv7m_start_algorithm only updates CONTROL when the requested + * mode differs from current — but if Zephyr was also in Thread + * mode with nPRIV=1, CONTROL is left untouched and the algorithm + * inherits unprivileged mode. + */ + struct reg_param reg_params[1]; + init_reg_param(®_params[0], "pmsk_bpri_fltmsk_ctrl", 32, PARAM_OUT); + buf_set_u32(reg_params[0].value, 0, 32, 0x00000000); + + LOG_DEBUG("AM13: starting flash algorithm"); + retval = target_start_algorithm(target, 0, NULL, 1, reg_params, + AM13_ALGO_BASE, 0, + &am13_info->armv7m_info); + + destroy_reg_param(®_params[0]); + + if (retval != ERROR_OK) { + LOG_ERROR("AM13: failed to start flash algorithm"); + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + } + + return retval; +} + +static int am13_algo_quit(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + + (void)target_halt(target); + + int retval = target_wait_algorithm(target, 0, NULL, 0, NULL, + 0, AM13_FLASH_TIMEOUT_MS, + &am13_info->armv7m_info); + + am13_clear_gsc_semaphore(bank); + + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + + return retval; +} + +static int am13_algo_wait_done(struct flash_bank *bank, uint32_t params_addr) +{ + struct target *target = bank->target; + uint32_t status = AM13_BUFFER_FULL; + int64_t start_ms = timeval_ms(); + int retval; + + while (status == AM13_BUFFER_FULL) { + retval = target_read_u32(target, params_addr + AM13_STATUS_OFFSET, + &status); + if (retval != ERROR_OK) + return retval; + + int64_t elapsed_ms = timeval_ms() - start_ms; + if (elapsed_ms > 500) + keep_alive(); + if (elapsed_ms > AM13_FLASH_TIMEOUT_MS) + break; + } + + if (status != AM13_BUFFER_EMPTY) { + LOG_ERROR("AM13: flash algorithm error, status=0x%08" PRIx32, + status); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static int am13_write(struct flash_bank *bank, const unsigned char *buffer, + unsigned int offset, unsigned int count) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + struct am13_algo_params algo_params[2]; + int retval; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + retval = am13_algo_init(bank); + if (retval != ERROR_OK) { + LOG_INFO("AM13: algorithm unavailable, falling back to direct writes"); + return am13_write_direct(bank, buffer, offset, count); + } + + static const uint32_t params_addr[] = { + AM13_ALGO_PARAMS_0, AM13_ALGO_PARAMS_1 + }; + static const uint32_t buffer_addr[] = { + AM13_ALGO_BUFFER_0, AM13_ALGO_BUFFER_1 + }; + + uint32_t address = bank->base + offset; + uint32_t index = 0; + int64_t start_ms = timeval_ms(); + + buf_set_u32(algo_params[0].cmd, 0, 32, AM13_CMD_ERASE_AND_PROGRAM); + buf_set_u32(algo_params[1].cmd, 0, 32, AM13_CMD_ERASE_AND_PROGRAM); + + while (count > 0) { + uint32_t size = MIN(count, AM13_SECTOR_SIZE_BYTES); + + retval = target_write_buffer(target, buffer_addr[index], + size, buffer); + if (retval != ERROR_OK) + break; + + buf_set_u32(algo_params[index].dest, 0, 32, address); + buf_set_u32(algo_params[index].len, 0, 32, size); + buf_set_u32(algo_params[index].status, 0, 32, AM13_BUFFER_FULL); + + /* Write dest/len/cmd/status only — preserve algorithm's buf_addr */ + retval = target_write_buffer(target, params_addr[index], + offsetof(struct am13_algo_params, buf_addr), + (uint8_t *)&algo_params[index]); + if (retval != ERROR_OK) + break; + + index ^= 1; + retval = am13_algo_wait_done(bank, params_addr[index]); + if (retval != ERROR_OK) + break; + + count -= size; + buffer += size; + address += size; + + if (timeval_ms() - start_ms > 500) + keep_alive(); + } + + /* Wait for the last submitted buffer */ + if (retval == ERROR_OK) { + index ^= 1; + retval = am13_algo_wait_done(bank, params_addr[index]); + } + + (void)am13_algo_quit(bank); + return retval; +} + +/* ---------- Probe ---------- */ + +static int am13_probe(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + uint32_t did, sramflash; + int retval; + + retval = target_read_u32(target, AM13_DID, &did); + if (retval != ERROR_OK) + return retval; + + if (((did & GENMASK(11, 1)) >> 1) != TI_MANUFACTURER_ID) { + LOG_ERROR("AM13: unexpected manufacturer ID in DID=0x%08" PRIx32, + did); + return ERROR_FAIL; + } + + am13_info->did = did; + + retval = target_read_u32(target, AM13_TRACEID, &am13_info->traceid); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u32(target, AM13_SRAMFLASH, &sramflash); + if (retval != ERROR_OK) + return retval; + + am13_info->main_flash_size_kb = sramflash & GENMASK(11, 0); + am13_info->main_flash_num_banks = (sramflash & GENMASK(13, 12)) >> 12; + am13_info->sram_size_kb = (sramflash & GENMASK(25, 16)) >> 16; + + free(bank->sectors); + bank->sectors = NULL; + + unsigned int num_sectors; + switch (bank->base) { + case AM13_FLASH_BASE_MAIN: + bank->size = am13_info->main_flash_size_kb * 1024; + num_sectors = bank->size / am13_info->sector_size; + break; + case AM13_FLASH_BASE_NONMAIN: + bank->size = am13_info->main_flash_num_banks * AM13_NONMAIN_SIZE_PER_BANK; + num_sectors = bank->size / am13_info->sector_size; + break; + default: + LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); + return ERROR_FAIL; + } + + if (num_sectors == 0) { + bank->num_sectors = 0; + bank->size = 0; + return ERROR_OK; + } + + bank->num_sectors = num_sectors; + bank->sectors = calloc(num_sectors, sizeof(struct flash_sector)); + if (!bank->sectors) + return ERROR_FAIL; + + for (unsigned int i = 0; i < num_sectors; i++) { + bank->sectors[i].offset = i * am13_info->sector_size; + bank->sectors[i].size = am13_info->sector_size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 0; + } + + LOG_INFO("AM13: %s flash: %u KB (%u sectors), %u bank(s), SRAM: %u KB", + (bank->base == AM13_FLASH_BASE_MAIN) ? "MAIN" : "NONMAIN", + (unsigned int)(bank->size / 1024), num_sectors, + am13_info->main_flash_num_banks, + am13_info->sram_size_kb); + + return ERROR_OK; +} + +static int am13_auto_probe(struct flash_bank *bank) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + + if (am13_info->did) + return ERROR_OK; + + return am13_probe(bank); +} + +static int get_am13_info(struct flash_bank *bank, + struct command_invocation *cmd) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + command_print_sameline(cmd, "AM13E23X: DID=0x%08" PRIx32 + " TRACEID=0x%08" PRIx32 + " banks=%u", + am13_info->did, am13_info->traceid, + am13_info->main_flash_num_banks); + return ERROR_OK; +} + +const struct flash_driver am13_flash = { + .name = "am13", + .flash_bank_command = am13_flash_bank_command, + .erase = am13_erase, + .protect = NULL, + .write = am13_write, + .read = default_flash_read, + .probe = am13_probe, + .auto_probe = am13_auto_probe, + .erase_check = default_flash_blank_check, + .protect_check = am13_protect_check, + .info = get_am13_info, + .free_driver_priv = default_flash_free_driver_priv, +}; diff --git a/src/flash/nor/am13e230x.h b/src/flash/nor/am13e230x.h new file mode 100644 index 0000000000..3849e5ad01 --- /dev/null +++ b/src/flash/nor/am13e230x.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + * + * Flash loader algorithm parameters for AM13E230X. + * Addresses must match the linker script in + * contrib/loaders/flash/am13e230x/am13e230x.lds + ***************************************************************************/ + +#ifndef OPENOCD_FLASH_NOR_AM13E230X_H +#define OPENOCD_FLASH_NOR_AM13E230X_H + +/* Algorithm is loaded at the base of SRAM */ +#define AM13_ALGO_BASE 0x20000000 + +/* Parameter blocks (two, for ping-pong) */ +#define AM13_ALGO_PARAMS_0 0x20002000 +#define AM13_ALGO_PARAMS_1 0x20002014 + +/* Data buffers (each one sector = 2 KB) */ +#define AM13_ALGO_BUFFER_0 0x20002100 +#define AM13_ALGO_BUFFER_1 0x20002900 + +/* Total working area needed */ +#define AM13_ALGO_WORKING_SIZE (AM13_ALGO_BUFFER_1 + 0x800 - AM13_ALGO_BASE) + +/* Handshake values (must match loader main.c) */ +#define AM13_BUFFER_EMPTY 0x00000000 +#define AM13_BUFFER_FULL 0xFFFFFFFF + +/* Offset of the status field within flash_params */ +#define AM13_STATUS_OFFSET 0x0C + +/* Commands (must match loader main.c) */ +#define AM13_CMD_NO_ACTION 0 +#define AM13_CMD_ERASE_ALL 1 +#define AM13_CMD_PROGRAM 2 +#define AM13_CMD_ERASE_AND_PROGRAM 3 +#define AM13_CMD_ERASE_SECTORS 4 + +/* Parameter block layout (matches struct flash_params in loader) */ +struct am13_algo_params { + uint8_t dest[4]; + uint8_t len[4]; + uint8_t cmd[4]; + uint8_t status[4]; + uint8_t buf_addr[4]; +}; + +#endif /* OPENOCD_FLASH_NOR_AM13E230X_H */ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index afb73a3fb2..3748292c77 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -240,6 +240,7 @@ const struct flash_driver *flash_driver_find_by_name(const char *name); // Keep in alphabetic order this list of drivers extern const struct flash_driver aduc702x_flash; extern const struct flash_driver aducm360_flash; +extern const struct flash_driver am13_flash; extern const struct flash_driver ambiqmicro_flash; extern const struct flash_driver artery_flash; extern const struct flash_driver at91sam3_flash; diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 094b5a76ba..fa3f315bac 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -19,6 +19,7 @@ static const struct flash_driver * const flash_drivers[] = { // Keep in alphabetic order the list of drivers &aduc702x_flash, &aducm360_flash, + &am13_flash, &ambiqmicro_flash, &artery_flash, &at91sam3_flash, -- |
|
From: <ge...@op...> - 2026-04-22 06:26:43
|
This is an automated email from Gerrit. "Sameer Srivastava <s-s...@ti...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9525 -- gerrit commit cb28a05c91e73629d2888ad8af6c30bde05dc69c Author: Sameer Srivastava <s-s...@ti...> Date: Sun Mar 8 12:10:37 2026 +0530 tcl: added am13e230x target and launchpad cfg - target defines SRAM work area and flash region - board selects xds110 interface and speed Signed-off-by: Sameer Srivastava <s-s...@ti...> Change-Id: I6cb9f52867a1a64895d9ff81f0c38b228578fc1a diff --git a/tcl/board/ti/am13e230x-launchpad.cfg b/tcl/board/ti/am13e230x-launchpad.cfg new file mode 100644 index 0000000000..2ca32ceaa8 --- /dev/null +++ b/tcl/board/ti/am13e230x-launchpad.cfg @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ +# + +source [find interface/xds110.cfg] +adapter speed 10000 +source [find target/ti/am13e230x.cfg] +init +reset halt diff --git a/tcl/target/ti/am13e230x.cfg b/tcl/target/ti/am13e230x.cfg new file mode 100644 index 0000000000..4bf0b608ff --- /dev/null +++ b/tcl/target/ti/am13e230x.cfg @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ +# +# Texas Instruments AM13E230X - ARM Cortex-M33 @ 200MHz +# + +source [find bitsbytes.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME AM13E230X +} + +if { [info exists CPUTAPID] } { + set _DAP_TAPID $CPUTAPID +} else { + set _DAP_TAPID 0x6ba00477 +} + +transport select jtag + +set _DAP_ID $_DAP_TAPID + +jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID + +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap + +if { [info exists WORKAREABASE] } { + set _WORKAREABASE $WORKAREABASE +} else { + set _WORKAREABASE 0x20000000 +} +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x18000 +} + +$_TARGETNAME configure -work-area-phys $_WORKAREABASE -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME.main am13 0x00000000 0 0 0 $_TARGETNAME +flash bank $_FLASHNAME.nonmain am13 0x60100000 0 0 0 $_TARGETNAME + +if {![using_hla]} { + cortex_m reset_config sysresetreq +} -- |
|
From: <ge...@op...> - 2026-04-22 06:26:40
|
This is an automated email from Gerrit. "Sameer Srivastava <s-s...@ti...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9526 -- gerrit commit f9f25125f68995287b29214402a80ca70a68b314 Author: Sameer Srivastava <s-s...@ti...> Date: Sun Mar 8 12:12:04 2026 +0530 contrib: loaders: add am13e230x flash loader algorithm Created a flash loader for AM13E230X that receives flash sectors via shared memory ping-pong buffers, similar to the CC26xx flash loader. Signed-off-by: Sameer Srivastava <s-s...@ti...> Change-Id: If5759b6f513cf94a0208d1bf4e95eb012a297d17 diff --git a/contrib/loaders/flash/am13e230x/Makefile b/contrib/loaders/flash/am13e230x/Makefile new file mode 100644 index 0000000000..689e4cdf85 --- /dev/null +++ b/contrib/loaders/flash/am13e230x/Makefile @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + +BIN2C = ../../../../src/helper/bin2char.sh + +CROSS_COMPILE ?= arm-none-eabi- +GCC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +FLAGS = -mcpu=cortex-m33 -mthumb -Os +FLAGS += -ffunction-sections -fdata-sections +FLAGS += -g -gdwarf-3 -gstrict-dwarf +FLAGS += -Wall -fno-strict-aliasing -fno-builtin +FLAGS += -nostdlib -nostartfiles + +CFLAGS = -c -I. + +OBJS := \ + startup.o \ + main.o \ + flash.o + +all: am13e230x_algo.inc + +%.o: %.c + @echo 'Building: $<' + $(GCC) $(FLAGS) $(CFLAGS) -o "$@" "$<" + +am13e230x_algo.out: $(OBJS) + @echo 'Linking: $@' + $(GCC) $(FLAGS) -o $@ $(OBJS) -Wl,-T"am13e230x.lds" + +%.bin: %.out + @echo 'Objcopy: $@' + $(OBJCOPY) -Obinary $< $@ + +%.inc: %.bin + @echo 'Bin2Char: $@' + $(BIN2C) < $< > $@ + rm $< $*.out + +clean: + rm -rf *.o *.d *.out *.bin *.inc *.map + +.PRECIOUS: %.bin + +.PHONY: all clean diff --git a/contrib/loaders/flash/am13e230x/am13e230x.lds b/contrib/loaders/flash/am13e230x/am13e230x.lds new file mode 100644 index 0000000000..db0fc1da76 --- /dev/null +++ b/contrib/loaders/flash/am13e230x/am13e230x.lds @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/****************************************************************************** + * + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + * + * Linker script for AM13E230X flash loader algorithm. + * Everything runs from SRAM. Params and buffers are at fixed addresses + * that the OpenOCD driver knows about (see am13e230x.h). + * + *****************************************************************************/ + +ENTRY( entry ) + +MEMORY +{ + /* Code, data, bss, stack */ + PROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x2000 + /* Params and data buffers at known addresses */ + BUFFERS (RWX) : ORIGIN = 0x20002000, LENGTH = 0x1100 +} + +SECTIONS +{ + .text : + { + _text = .; + *(.entry*) + *(.text*) + _etext = .; + } > PROGRAM + + .data : + { + _data = .; + *(.rodata*) + *(.data*) + _edata = .; + } > PROGRAM + + .bss : + { + __bss_start__ = .; + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + __bss_end__ = .; + } > PROGRAM + + .stack : + { + _stack = .; + *(.stack*) + _estack = .; + } > PROGRAM + + .buffers : + { + _buffers = .; + *(.buffers.params) + . = 0x100; + *(.buffers.buf0) + *(.buffers.buf1) + _ebuffers = .; + } > BUFFERS +} diff --git a/contrib/loaders/flash/am13e230x/am13e230x_algo.inc b/contrib/loaders/flash/am13e230x/am13e230x_algo.inc new file mode 100644 index 0000000000..3ebb130274 --- /dev/null +++ b/contrib/loaders/flash/am13e230x/am13e230x_algo.inc @@ -0,0 +1,785 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x4f,0xf0,0x00,0x00,0x80,0xf3,0x14,0x88, +0xbf,0xf3,0x6f,0x8f,0xdf,0xf8,0x18,0xd0,0x06,0x48,0x07,0x49,0x4f,0xf0,0x00,0x02, +0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0x07,0xf8,0xfe,0xe7, +0x68,0x04,0x00,0x20,0xd8,0x02,0x00,0x20,0xd8,0x02,0x00,0x20,0x2d,0xe9,0xf0,0x47, +0x00,0x25,0x34,0x4c,0x34,0x4b,0x4f,0xf0,0x14,0x09,0x23,0x61,0x33,0x4b,0xa8,0x46, +0x63,0x62,0x23,0x7b,0x25,0x73,0x63,0x7b,0x65,0x73,0xa3,0x7b,0xa5,0x73,0xe3,0x7b, +0xe5,0x73,0x94,0xf8,0x20,0x30,0x84,0xf8,0x20,0x50,0x94,0xf8,0x21,0x30,0x84,0xf8, +0x21,0x50,0x94,0xf8,0x22,0x30,0x84,0xf8,0x22,0x50,0x94,0xf8,0x23,0x30,0x84,0xf8, +0x23,0x50,0x00,0xf0,0x8f,0xf8,0x09,0xfb,0x05,0xf7,0xe6,0x19,0x06,0xf1,0x08,0x02, +0x53,0x68,0x00,0x2b,0xfc,0xd0,0xb3,0x68,0x03,0x2b,0x0c,0xd0,0x04,0x2b,0x17,0xd0, +0x02,0x2b,0x0c,0xd0,0x40,0xf2,0x03,0x12,0x14,0x23,0x03,0xfb,0x05,0x43,0xda,0x60, +0x00,0xf0,0x80,0xf8,0xfe,0xe7,0xe0,0x59,0x00,0xf0,0x84,0xf8,0x38,0xbb,0x30,0x69, +0xe1,0x59,0x72,0x68,0x00,0xf0,0x98,0xf8,0x48,0xb1,0x4f,0xf4,0x81,0x72,0xeb,0xe7, +0x54,0xf8,0x07,0xa0,0xe3,0x59,0x72,0x68,0x9e,0x18,0x56,0x45,0x10,0xd8,0x09,0xfb, +0x05,0x43,0x1a,0x7b,0x83,0xf8,0x0c,0x80,0x5a,0x7b,0x83,0xf8,0x0d,0x80,0x9a,0x7b, +0x83,0xf8,0x0e,0x80,0xda,0x7b,0x85,0xf0,0x01,0x05,0x83,0xf8,0x0f,0x80,0xc2,0xe7, +0x50,0x46,0x00,0xf0,0x5f,0xf8,0x10,0xb9,0x0a,0xf5,0x00,0x6a,0xe5,0xe7,0x40,0xf2, +0x01,0x12,0xc9,0xe7,0x00,0x20,0x00,0x20,0x00,0x21,0x00,0x20,0x00,0x29,0x00,0x20, +0xfe,0xe7,0x00,0x00,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x01,0x23,0x0d,0x49, +0xc1,0xf8,0x00,0x31,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x4f,0xf4,0x00,0x03, +0x01,0x3b,0xd1,0xf8,0xd0,0x23,0x0a,0xd0,0x02,0xf0,0x07,0x00,0x04,0x28,0xf7,0xd0, +0x12,0xf0,0x02,0x0f,0x0c,0xbf,0x6f,0xf0,0x01,0x00,0x00,0x20,0x70,0x47,0x4f,0xf0, +0xff,0x30,0x70,0x47,0x00,0x30,0x04,0x40,0x05,0x22,0x0d,0x4b,0xc3,0xf8,0x04,0x21, +0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x01,0x22,0xc3,0xf8,0x00,0x21,0xbf,0xf3, +0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x4f,0xf4,0x00,0x02,0xd3,0xf8,0xd0,0x03,0x10,0xf0, +0x04,0x00,0x00,0xd1,0x70,0x47,0x01,0x3a,0xf7,0xd1,0x4f,0xf0,0xff,0x30,0x70,0x47, +0x00,0x30,0x04,0x40,0x01,0x22,0x02,0x4b,0xc3,0xf8,0x00,0x28,0x70,0x47,0x00,0xbf, +0x00,0x70,0x04,0x40,0x01,0x22,0x02,0x4b,0xc3,0xf8,0x04,0x28,0x70,0x47,0x00,0xbf, +0x00,0x70,0x04,0x40,0x08,0xb5,0x01,0x46,0xff,0xf7,0xce,0xff,0x78,0xb9,0x42,0x22, +0x08,0x4b,0x21,0xf0,0x0f,0x01,0xc3,0xf8,0xd0,0x01,0xc3,0xf8,0xd4,0x01,0xc3,0xf8, +0x04,0x21,0xc3,0xf8,0x20,0x11,0xbd,0xe8,0x08,0x40,0xff,0xf7,0x9b,0xbf,0x4f,0xf0, +0xff,0x30,0x08,0xbd,0x00,0x30,0x04,0x40,0x2d,0xe9,0xf0,0x4f,0x06,0x46,0x89,0x46, +0x15,0x46,0xdf,0xf8,0xc8,0xa0,0xdf,0xf8,0xc8,0x80,0x85,0xb0,0x0d,0xb9,0x28,0x46, +0x4c,0xe0,0x10,0x2d,0x2f,0x46,0x28,0xbf,0x10,0x27,0x7b,0x07,0x4e,0xd0,0x0f,0x23, +0x6a,0x46,0x6c,0x46,0xff,0x20,0xf9,0x1d,0x21,0xf0,0x07,0x01,0x01,0x3b,0x02,0xf8, +0x01,0x0b,0xfb,0xd2,0x22,0x46,0x33,0x46,0xf0,0x19,0x83,0x42,0x39,0xd1,0x08,0x29, +0x1d,0xbf,0x4f,0xf0,0x01,0x0b,0x0b,0xfa,0x01,0xfb,0x0b,0xf1,0xff,0x3b,0xdf,0xf8, +0x84,0xb0,0x18,0xbf,0x4b,0xf4,0x40,0x3b,0xff,0xf7,0x86,0xff,0x00,0x22,0x01,0x23, +0xca,0xf8,0xd0,0x21,0xca,0xf8,0xd4,0x21,0xca,0xf8,0x04,0x31,0x29,0xf0,0x0f,0x03, +0xca,0xf8,0x24,0xb1,0xca,0xf8,0x20,0x31,0xc9,0xf3,0x01,0x13,0xca,0xf8,0x2c,0x31, +0xa3,0x78,0x60,0x78,0x1b,0x04,0x43,0xea,0x00,0x23,0x20,0x78,0x04,0x34,0x03,0x43, +0x14,0xf8,0x01,0x0c,0x43,0xea,0x00,0x63,0x42,0xf8,0x08,0x30,0x04,0x32,0x91,0x42, +0xee,0xd8,0xff,0xf7,0x3f,0xff,0x60,0xb1,0x4f,0xf0,0xff,0x30,0x05,0xb0,0xbd,0xe8, +0xf0,0x8f,0x13,0xf8,0x01,0xcb,0x02,0xf8,0x01,0xcb,0xbe,0xe7,0x34,0x46,0x39,0x46, +0xbd,0xe7,0xb9,0x44,0x3e,0x44,0xed,0x1b,0xa0,0xe7,0x00,0xbf,0x00,0x30,0x04,0x40, +0x30,0x31,0x04,0x40,0xff,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,... [truncated message content] |
|
From: <ge...@op...> - 2026-04-19 11:44:34
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9582 -- gerrit commit 2e96a667f6f3b2b96fd6387daad7620af8195519 Author: Marc Schink <de...@za...> Date: Sat Apr 18 16:19:56 2026 +0200 adapters/xvc: Fix xvc_init_tcp() Avoid calling setsockopt() on an invalid socket when the TCP connection setup fails. While at it, restructure the code and apply const-correctness. Change-Id: I1dc3da89321c5d0b4c76c145501c80206a3c9de4 Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index 8a1bc7c7fd..d5a5810f35 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -324,10 +324,13 @@ static int xvc_reset(int trst, int srst) static int xvc_init_tcp(int *fd) { - struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM}; - LOG_INFO("Connecting to %s:%s", xvc_host ? xvc_host : "localhost", xvc_port); + const struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM + }; + struct addrinfo *result; // Obtain address(es) matching host/port. int s = getaddrinfo(xvc_host, xvc_port, &hints, &result); @@ -350,20 +353,12 @@ static int xvc_init_tcp(int *fd) if (*fd == (int)INVALID_SOCKET) continue; #endif - if (connect(*fd, rp->ai_addr, rp->ai_addrlen) != -1) break; close_socket(*fd); } - /* We work hard to collapse the writes into the minimum number, so when - * we write something we want to get it to the other end of the - * connection as fast as possible. */ - int one = 1; - // On Windows optval has to be a const char *. - setsockopt(*fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)); - freeaddrinfo(result); if (!rp) { @@ -371,6 +366,13 @@ static int xvc_init_tcp(int *fd) return ERROR_FAIL; } + /* We work hard to collapse the writes into the minimum number, so when + * we write something we want to get it to the other end of the + * connection as fast as possible. */ + int one = 1; + // On Windows optval has to be a const char *. + setsockopt(*fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)); + return ERROR_OK; } -- |
|
From: <ge...@op...> - 2026-04-19 11:44:34
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9580 -- gerrit commit d0157905af08a1a2e3a33b02bc4c9e2ed272824d Author: Marc Schink <de...@za...> Date: Sat Apr 18 14:48:05 2026 +0200 adapters/xvc: Use proper data types Use 'unsigned int' and 'size_t' instead of 'int' where appropriate. Change-Id: I26514081312260d21af862a91a6e10fb577ea97b Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index 6e70936e07..3d1c431ce1 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -133,8 +133,8 @@ static int xvc_flush(void) unsigned int number_of_bytes = xvc_bits_to_bytes(xvc_used_bits); // Creates the header. const char *shift = "shift:"; - int shift_len = strlen(shift); - int cp_offset = 0; + size_t shift_len = strlen(shift); + size_t cp_offset = 0; // Copies the header. memcpy(xvc_send_buf + cp_offset, shift, shift_len); // Updates the offset. @@ -149,11 +149,11 @@ static int xvc_flush(void) memcpy(xvc_send_buf + cp_offset, xvc_tdi_buf, number_of_bytes); cp_offset += number_of_bytes; // Updates the number of bytes used. - LOG_DEBUG("XVC flush: cp_offset: %d", cp_offset); + LOG_DEBUG("XVC flush: cp_offset: %zu", cp_offset); LOG_DEBUG("XVC flush: used_bits: %d", xvc_used_bits); int written = write_socket(xvc_fd, xvc_send_buf, cp_offset); - if (written != cp_offset) { + if (written != (int)cp_offset) { LOG_ERROR("Error writing socket in %s", __func__); return ERROR_FAIL; } @@ -205,9 +205,10 @@ static int xvc_queue(const uint8_t *tms, unsigned int tms_offset, const uint8_t static int xvc_getinfo(void) { const char *getinfo = "getinfo:"; - int len = strlen(getinfo); + size_t len = strlen(getinfo); int written = write_socket(xvc_fd, getinfo, len); - if (written != len) { + + if (written != (int)len) { LOG_ERROR("%s: write", __func__); return ERROR_FAIL; } @@ -559,11 +560,11 @@ static int xvc_tap_path_move(struct pathmove_command *cmd) return ERROR_OK; } -static unsigned int xvc_tap_stableclocks(int num_cycles) +static unsigned int xvc_tap_stableclocks(unsigned int num_cycles) { uint8_t tms = (tap_get_state() == TAP_RESET ? 0xff : 0); - for (int i = 0; i < num_cycles; i++) + for (unsigned int i = 0; i < num_cycles; i++) xvc_queue(&tms, 0, NULL, 0, NULL, 0, 1); return ERROR_OK; -- |
|
From: <ge...@op...> - 2026-04-19 11:44:19
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9581 -- gerrit commit 946f29ac893641204ea01cad46ec26cf6600235b Author: Marc Schink <de...@za...> Date: Sat Apr 18 14:48:32 2026 +0200 adapters/xvc: Handle return values during initialization Propagate errors from xvc_getinfo() and xvc_set_tck() during adapter initialization instead of silently ignoring them. Change-Id: I8cb86194b8cdbbccb1a49e0e97d50905c62af2ec Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index 3d1c431ce1..8a1bc7c7fd 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -462,16 +462,23 @@ static int xvc_init(void) xvc_tck = 1000; LOG_DEBUG("Initializing XVC driver"); - int err = ERROR_OK; + int ret; + if (!xvc_port) - err = xvc_init_unix(&xvc_fd); + ret = xvc_init_unix(&xvc_fd); else - err = xvc_init_tcp(&xvc_fd); - if (err != ERROR_OK) - return err; + ret = xvc_init_tcp(&xvc_fd); + + if (ret != ERROR_OK) + return ret; + + ret = xvc_getinfo(); + if (ret != ERROR_OK) + return ret; - xvc_getinfo(); - xvc_set_tck(); + ret = xvc_set_tck(); + if (ret != ERROR_OK) + return ret; LOG_DEBUG("XVC driver initialized"); -- |
|
From: <ge...@op...> - 2026-04-19 11:44:19
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9583 -- gerrit commit ec850335ee40ea22e24f51b241d2736fdafe33b7 Author: Marc Schink <de...@za...> Date: Sun Apr 19 12:01:14 2026 +0200 adapters/xvc: Remove noisy debug output The current debug output clutters the logs while adding little useful information, so remove it. Change-Id: I4b6261520e471194be7807e4205cd1ba05df15bc Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index d5a5810f35..9a38ed1b4c 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -149,8 +149,6 @@ static int xvc_flush(void) memcpy(xvc_send_buf + cp_offset, xvc_tdi_buf, number_of_bytes); cp_offset += number_of_bytes; // Updates the number of bytes used. - LOG_DEBUG("XVC flush: cp_offset: %zu", cp_offset); - LOG_DEBUG("XVC flush: used_bits: %d", xvc_used_bits); int written = write_socket(xvc_fd, xvc_send_buf, cp_offset); if (written != (int)cp_offset) { -- |
|
From: <ge...@op...> - 2026-04-17 13:24:15
|
This is an automated email from Gerrit. "Alexandra Kulyatskaya <a.k...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9579 -- gerrit commit ef486bfd76b58a400f46045cf9d8f9afd73f3c36 Author: Kulyatskaya Alexandra <a.k...@sy...> Date: Fri Apr 10 13:20:21 2026 +0300 [src/server] Support x packet Implement the binary memory read GDB packet 'x addr,length'. Change-Id: I7e4aab1c5e9fd26bb03f19f133b9d94aee7f22a1 Signed-off-by: Kulyatskaya Alexandra <a.k...@sy...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index f59eb5029e..a06133bf31 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1532,42 +1532,37 @@ static int gdb_error(struct connection *connection, int retval) return ERROR_OK; } -static int gdb_read_memory_packet(struct connection *connection, - char const *packet, int packet_size) +static bool parse_packet_addr_len(char const *packet, uint64_t *addr, uint32_t *len) { - struct target *target = get_available_target_from_connection(connection); char *separator; - uint64_t addr = 0; - uint32_t len = 0; - - uint8_t *buffer; - char *hex_buffer; - - int retval = ERROR_OK; /* skip command character */ packet++; - addr = strtoull(packet, &separator, 16); + *addr = strtoull(packet, &separator, 16); - if (*separator != ',') { - LOG_ERROR("incomplete read memory packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; + if (*separator != ',') + return false; + + errno = 0; + long signed_len = strtol(separator + 1, NULL, 16); + if (errno == ERANGE || signed_len < 0 || (unsigned long)signed_len > UINT32_MAX) { + return false; } - len = strtoul(separator + 1, NULL, 16); + *len = (uint32_t)signed_len; - if (!len) { - LOG_WARNING("invalid read memory packet received (len == 0)"); - gdb_put_packet(connection, "", 0); - return ERROR_OK; - } + return true; +} - buffer = malloc(len); +static int gdb_read_memory(const struct connection *connection, + uint8_t *buffer, uint64_t addr, uint32_t len) +{ + struct target *target = get_available_target_from_connection(connection); LOG_DEBUG("addr: 0x%16.16" PRIx64 ", len: 0x%8.8" PRIx32, addr, len); - retval = ERROR_NOT_IMPLEMENTED; + int retval = ERROR_NOT_IMPLEMENTED; if (target->rtos) retval = rtos_read_buffer(target, addr, len, buffer); if (retval == ERROR_NOT_IMPLEMENTED) @@ -1591,8 +1586,47 @@ static int gdb_read_memory_packet(struct connection *connection, retval = ERROR_OK; } + return retval; +} + +static int gdb_read_memory_packet(struct connection *connection, + char const *packet, int packet_size) +{ + uint64_t addr; + uint32_t len; + + uint8_t *buffer; + char *hex_buffer; + + int retval; + + if (!parse_packet_addr_len(packet, &addr, &len)) { + LOG_ERROR("incomplete read memory packet received, dropping connection"); + return ERROR_SERVER_REMOTE_CLOSED; + } + if (!len) { + LOG_WARNING("invalid read memory packet received (len == 0)"); + gdb_put_packet(connection, "", 0); + return ERROR_OK; + } + + buffer = malloc(len); + if (!buffer) { + LOG_ERROR("Unable to allocate memory"); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + retval = gdb_read_memory(connection, buffer, addr, len); + if (retval == ERROR_OK) { hex_buffer = malloc(len * 2 + 1); + if (!hex_buffer) { + LOG_ERROR("Unable to allocate memory for hex buffer"); + gdb_send_error(connection, 01); + free(buffer); + return ERROR_OK; + } size_t pkt_len = hexify(hex_buffer, buffer, len, len * 2 + 1); @@ -1607,6 +1641,83 @@ static int gdb_read_memory_packet(struct connection *connection, return retval; } +static size_t escape_binary_data(const uint8_t *data, char *out, size_t data_len) +{ + assert(out); + + size_t out_pos = 1; + out[0] = 'b'; + + for (size_t i = 0; i < data_len; ++i) { + uint8_t c = data[i]; + /* See the logic for escaping binary data here: + * https://sourceware.org/gdb/current/onlinedocs/gdb.html/Overview.html#Binary-Data */ + if (c == 0x23 || c == 0x24 || c == 0x7d || c == 0x2a) { + out[out_pos++] = 0x7d; + out[out_pos++] = c ^ 0x20; + } else { + out[out_pos++] = c; + } + } + + return out_pos; +} + +static int gdb_read_memory_packet_binary(struct connection *connection, + char const *packet, int packet_size) +{ + uint64_t addr; + uint32_t len; + + if (!parse_packet_addr_len(packet, &addr, &len)) { + LOG_ERROR("incomplete read memory packet received, dropping connection"); + return ERROR_SERVER_REMOTE_CLOSED; + } + if (!len) { + LOG_WARNING("invalid read memory packet received (len == 0)"); + gdb_put_packet(connection, "", 0); + return ERROR_OK; + } + + char *out_buffer = NULL; + uint8_t *buffer = malloc(len); + if (!buffer) { + LOG_ERROR("Unable to allocate memory"); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + int retval = gdb_read_memory(connection, buffer, addr, len); + if (retval != ERROR_OK) { + retval = gdb_error(connection, retval); + goto cleanup; + } + + /* len * 2 : each byte may need escaping → 2 bytes max per input byte + * +1 : for 'b' prefix + * +1 : for null terminator */ + out_buffer = malloc(len * 2 + 1 + 1); + if (!out_buffer) { + LOG_ERROR("Unable to allocate memory for output buffer"); + gdb_send_error(connection, 01); + goto cleanup; + } + size_t pkt_len = escape_binary_data(buffer, out_buffer, len); + if (pkt_len < len || INT_MAX <= pkt_len) { + LOG_ERROR("Escape binary data failed: invalid output length %zu " + "(input: %" PRIu32 ", max: %d)", pkt_len, len, INT_MAX); + gdb_send_error(connection, ERANGE); + } else { + retval = gdb_put_packet(connection, out_buffer, pkt_len); + } + +cleanup: + free(out_buffer); + free(buffer); + + return retval; +} + static int gdb_write_memory_packet(struct connection *connection, char const *packet, int packet_size) { @@ -2942,7 +3053,7 @@ static int gdb_query_packet(struct connection *connection, &buffer, &pos, &size, - "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+", + "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+;binary-upload+", GDB_BUFFER_SIZE, (gdb_use_memory_map && (flash_get_bank_count() > 0)) ? '+' : '-', gdb_target_desc_supported ? '+' : '-'); @@ -3735,6 +3846,11 @@ static int gdb_input_inner(struct connection *connection) retval = gdb_write_memory_binary_packet(connection, packet, packet_size); gdb_con->output_flag = GDB_OUTPUT_NO; break; + case 'x': + gdb_con->output_flag = GDB_OUTPUT_NOTIF; + retval = gdb_read_memory_packet_binary(connection, packet, packet_size); + gdb_con->output_flag = GDB_OUTPUT_NO; + break; case 'k': if (gdb_con->extended_protocol) { gdb_con->attached = false; -- |
|
From: <ge...@op...> - 2026-04-17 13:06:02
|
This is an automated email from Gerrit. "Alexandra Kulyatskaya <a.k...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9578 -- gerrit commit c5c25dbe611526573d0674bc16788e24afaebe01 Author: Kulyatskaya Alexandra <a.k...@sy...> Date: Fri Apr 10 13:21:06 2026 +0300 constify connection parameter in get_available_target_from_connection Make the connection parameter const since the function doesn't modify it. Change-Id: I703e0205a448e686fca28989b896a842fa27a5dc Signed-off-by: Kulyatskaya Alexandra <a.k...@sy...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index f59eb5029e..3e90b7b589 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -157,7 +157,7 @@ static char gdb_running_type; * the command fail. If gdb was aware that targets can be unavailable we * wouldn't need this logic. */ -struct target *get_available_target_from_connection(struct connection *connection) +struct target *get_available_target_from_connection(const struct connection *connection) { struct gdb_service *gdb_service = connection->service->priv; struct target *target = gdb_service->target; -- |
|
From: <ge...@op...> - 2026-04-13 16:01:31
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9577 -- gerrit commit 1fea1a254b3d545e8ea97d4ae195648e57833054 Author: Marc Schink <de...@za...> Date: Mon Apr 13 15:58:47 2026 +0000 tcl/board/st: Add NUCLEO-U3C5ZI-Q config Tested on NUCLEO-U3C5ZI-Q development board. Change-Id: I236f1fd3c0b75422f125cf4466f245bbb42893b1 Signed-off-by: Marc Schink <de...@za...> diff --git a/tcl/board/st/nucleo-u3c5zi-q.cfg b/tcl/board/st/nucleo-u3c5zi-q.cfg new file mode 100644 index 0000000000..21b8439c1a --- /dev/null +++ b/tcl/board/st/nucleo-u3c5zi-q.cfg @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# NUCLEO-U3C5ZI-Q +# https://www.st.com/en/evaluation-tools/nucleo-u3c5zi-q.html + +source [find interface/stlink.cfg] + +transport select swd + +source [find target/stm32u3x.cfg] + +reset_config srst_only -- |
|
From: Leonardo C. <cap...@gm...> - 2026-04-13 07:43:27
|
Dear OpenOCD dev community, I'm the maintainer of fpgacapzero (or fcapz) https://github.com/lcapossio/fpgacapZero/ an open-source cross-vendor FPGA JTAG debug cores, including logic analyzer (ELA), embedded I/O (EIO), JTAG to AXI bridge, etc. I have AMD/Xilinx hw_server backend working and have implemented OpenOCD basic functionality but I'm not able to test it. I'm looking for help in an honest assessment of my openOCD backend and what are the best practices. Also if you can help with testing different cables it'd be really good too. Any help is appreciated and hopefully it will be of use to everyone. Cheers, Leo |
|
From: <ge...@op...> - 2026-04-10 18:00:38
|
This is an automated email from Gerrit. "Richard Pasek <rp...@go...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9576 -- gerrit commit 95fe32a9b1c236d2eff790b2ffd446a414021261 Author: Richard Pasek <rp...@go...> Date: Fri Apr 10 13:57:59 2026 -0400 linuxspidev: Transition to LOG_CUSTOM_LEVEL_N() This change allows for printing spi_exchanges without having to enable compile time defines Change-Id: I4f434da519a4b0a28c12c14e562009c2dbf50f50 Signed-off-by: Richard Pasek <rp...@go...> diff --git a/src/jtag/drivers/linuxspidev.c b/src/jtag/drivers/linuxspidev.c index 396f1a19a9..d4e0f8646c 100644 --- a/src/jtag/drivers/linuxspidev.c +++ b/src/jtag/drivers/linuxspidev.c @@ -9,12 +9,11 @@ * Implementation of SWD protocol with a Linux SPI device. */ -/* Uncomment to log SPI exchanges (very verbose, slows things down a lot) - * - * A quick note on interpreting SPI exchange messages: +/* A quick note on interpreting SPI exchange messages (enabled with + * LOG_LVL_DEBUG_IO): * * This implementation works by performing SPI exchanges with MOSI and MISO - * tied together with a 1K resistor. This combined signal becomes SWDIO. + * tied together with a 100 ohm resistor. This combined signal becomes SWDIO. * * Since we are performing SPI exchanges, (reading and writing at the same * time) this means when the target isn't driving SWDIO, what is written by @@ -37,9 +36,7 @@ * ^^ * || * Command packet from host - * */ -// #define LOG_SPI_EXCHANGE #ifdef HAVE_CONFIG_H #include "config.h" @@ -111,9 +108,7 @@ static void spidev_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_ static void spi_exchange(const uint8_t *tx_data, uint8_t *rx_data, unsigned int len) { -#ifdef LOG_SPI_EXCHANGE - LOG_OUTPUT("exchange: len=%u\n", len); -#endif // LOG_SPI_EXCHANGE + LOG_DEBUG_IO("exchange: len=%u", len); if (len == 0) { LOG_DEBUG("exchange with no length"); @@ -135,14 +130,13 @@ static void spi_exchange(const uint8_t *tx_data, uint8_t *rx_data, unsigned int for (unsigned int i = 0; i < len; i++) tx_flip_buf[i] = flip_u32(tx_data[i], 8); -#ifdef LOG_SPI_EXCHANGE if (len != 0) { - LOG_OUTPUT(" tx_buf="); + LOG_CUSTOM_LEVEL_N(LOG_LVL_DEBUG_IO, " tx_buf="); for (unsigned int i = 0; i < len; i++) - LOG_OUTPUT("%.2" PRIx8 " ", tx_flip_buf[i]); + LOG_CUSTOM_LEVEL_N(LOG_LVL_DEBUG_IO, "%.2" PRIx8 " ", tx_flip_buf[i]); + + LOG_CUSTOM_LEVEL_N(LOG_LVL_DEBUG_IO, "\n"); } - LOG_OUTPUT("\n"); -#endif // LOG_SPI_EXCHANGE } // Transmit the MSB buffer to SPI device. struct spi_ioc_transfer tr = { @@ -165,14 +159,11 @@ static void spi_exchange(const uint8_t *tx_data, uint8_t *rx_data, unsigned int } if (rx_data) { -#ifdef LOG_SPI_EXCHANGE - if (len != 0) { - LOG_OUTPUT(" rx_buf="); - for (unsigned int i = 0; i < len; i++) - LOG_OUTPUT("%.2" PRIx8 " ", rx_data[i]); - } - LOG_OUTPUT("\n"); -#endif // LOG_SPI_EXCHANGE + LOG_CUSTOM_LEVEL_N(LOG_LVL_DEBUG_IO, " rx_buf="); + for (unsigned int i = 0; i < len; i++) + LOG_CUSTOM_LEVEL_N(LOG_LVL_DEBUG_IO, "%.2" PRIx8 " ", rx_data[i]); + + LOG_CUSTOM_LEVEL_N(LOG_LVL_DEBUG_IO, "\n"); // Reverse MSB to LSB for (unsigned int i = 0; i < len; i++) -- |
|
From: <ge...@op...> - 2026-04-10 18:00:34
|
This is an automated email from Gerrit. "Richard Pasek <rp...@go...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9575 -- gerrit commit 874ad640380e06224d8b90fd9e051879dacb2e28 Author: Richard Pasek <rp...@go...> Date: Fri Apr 10 13:00:19 2026 -0400 log: Add LOG_CUSTOM_LEVEL_N() macro At times it's desirable to log without line feeds at different debug levels. LOG_CUSTOM_LEVEL_N() exposes this functionality. Change-Id: I6624a64f10f37d3200e9bc6c410efbc07740c3b4 Signed-off-by: Richard Pasek <rp...@go...> diff --git a/src/helper/log.h b/src/helper/log.h index 01917abe23..62193400ce 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -138,6 +138,13 @@ extern int debug_level; expr); \ } while (0) +#define LOG_CUSTOM_LEVEL_N(level, expr ...) \ + do { \ + enum log_levels _level = level; \ + if (LOG_LEVEL_IS(_level)) \ + LOG_OUTPUT(expr); \ + } while (0) + #define LOG_INFO(expr ...) \ log_printf_lf(LOG_LVL_INFO, __FILE__, __LINE__, __func__, expr) -- |
|
From: <ge...@op...> - 2026-04-09 14:30:44
|
This is an automated email from Gerrit. "Name of user not set <fre...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9524 -- gerrit commit bc33cc16c865db7d176f4311abedda13f38fbdd2 Author: Frederic Boyer <fre...@mi...> Date: Thu Apr 9 16:29:04 2026 +0200 tcl: add SAMA7D6 target and SAMA7D65 Curiosity board configuration Add target configuration for the Microchip SAMA7D6 series (Cortex-A7 based MPU). Supports both JTAG and SWD interfaces. Add board configuration for the SAMA7D65 Curiosity board. Link: https://www.microchip.com/en-us/product/sama7d65 Link: https://www.microchip.com/en-us/development-tool/EV63J76A Change-Id: I94085babaf1b2f4ce92a44ed900128fc6093f397 Signed-off-by: Frederic Boyer <fre...@mi...> diff --git a/tcl/board/microchip/sama7d65_curiosity.cfg b/tcl/board/microchip/sama7d65_curiosity.cfg new file mode 100644 index 0000000000..73d655912d --- /dev/null +++ b/tcl/board/microchip/sama7d65_curiosity.cfg @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Board configuration for Microchip SAMA7D65 Curiosity Board +# https://www.microchip.com/en-us/development-tool/EV63J76A +# Datasheet: DS60001851 +# User Guide: DS50003806 +# +# Debug Interface Selection: +# An external JTAG/SWD probe must be connected to J38. +# + +# +# IMPORTANT: +# First-time JTAG Connection on blank board (no AT91Bootstrap in NVM): +# 1. Power on the board via J3 (USB Type-C) or J1 (DC jack) +# 2. ROM code searches for valid boot media +# 3. No valid code found -> ROM enters SAM-BA Monitor +# 4. SAM-BA Monitor enables JTAG -- OpenOCD can now connect +# To force SAM-BA entry on a board with programmed NVM: +# - Remove JP9 (J36) to disable NAND Flash boot [2] +# - Remove JP10 (J39) to disable QSPI Flash boot [2] +# - Remove any SD card from J10 +# +# Typical Boot sequence (when debugging via JTAG/SWD): +# 1. Load AT91Bootstrap to SRAM (0x00100000) +# - Initializes clocks, DDR, peripherals, disables watchdog +# 2. Load application to DDR (0x60000000) +# - Zephyr, Linux, or bare-metal application +# - DDR must be initialized by AT91Bootstrap first +# +# Reset sources on this board: +# - Power-on reset from MCP16502 PMIC +# - User push button SW4 (Board Reset, connected to NRST) +# - External JTAG probe reset via J38 pin 15 (NRST) +# +# Usage with JTAG (default): +# openocd -f interface/jlink.cfg -f board/microchip/sama7d65_curiosity.cfg +# +# Usage with SWD: +# openocd -f interface/jlink.cfg -c "transport select swd" \ +# -f board/microchip/sama7d65_curiosity.cfg + +# Default to JTAG -- silently ignored if already selected +catch { transport select jtag } + +# Target configuration (supports both JTAG and SWD) +source [find target/microchip/sama7d6.cfg] + +# Board-specific adapter speed +# Start at lower speed for reliable initial connection. +# Speed increases to 4 MHz after reset-init event (configured in target file). +adapter speed 1000 + +# Reset configuration for external probe on J38. +# Both SRST (pin 15/NRST) and TRST (pin 3/NTRST) are available +# on the 20-pin JTAG header. +# NTRST (PC22) has an internal pull-up -- safe to connect. +# +# srst_nogate: SRST is not gated by the JTAG state machine -- +# required because NRST resets the entire chip including debug logic. +# +# For probes with only SRST wired (no TRST), use instead: +# reset_config srst_only srst_nogate +# +reset_config trst_and_srst srst_nogate diff --git a/tcl/target/microchip/sama7d6.cfg b/tcl/target/microchip/sama7d6.cfg new file mode 100644 index 0000000000..650a6e01a1 --- /dev/null +++ b/tcl/target/microchip/sama7d6.cfg @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Target configuration for Microchip SAMA7D6 series +# +# Cortex-A7 based Microprocessor Unit (MPU) +# https://www.microchip.com/en-us/product/sama7d65 +# Datasheet: DS60001851 +# +# SAMA7D6 series currently includes: +# - SAMA7D65 +# +# Supports both JTAG and SWD transports. +# Select transport before sourcing this file: +# -c "transport select jtag" +# -c "transport select swd" +# If not specified, the adapter driver will auto-select. +# +# IMPORTANT: JTAG/SWD Access Requires ROM Code Completion +# The SAMA7D65 ROM code disables JTAG during boot. +# JTAG is enabled only after one of: +# a) The ROM code finds a valid boot image (e.g., AT91Bootstrap) +# and jumps to SRAM -- JTAG is enabled at that point +# b) No valid NVM found -- ROM code enters SAM-BA Monitor, +# enables USB + UART + JTAG connection +# +# On a blank/fresh board with no NVM programmed: +# - Power on the board +# - Wait for ROM code to enter SAM-BA Monitor +# - JTAG is then enabled automatically +# +# JTAG/Debug Security (OTP Fuses): +# OTPC_UHC0R.JTAGDIS[7:0] = 0x00 (default): JTAG enabled +# OTPC_UHC0R.JTAGDIS[7:0] != 0x00: JTAG permanently disabled +# OTPC_UHC0R.SECDBG[7:0] = 0x00 (default): Secure debug allowed +# OTPC_UHC0R.SECDBG[7:0] != 0x00: Secure debug permanently forbidden +# WARNING: If these OTP fuses are blown, JTAG/SWD is permanently disabled. +# +# Hardware watchdog warning: +# When connecting before AT91Bootstrap runs, the hardware watchdog +# may reset the chip periodically, causing transient DAP errors. +# OpenOCD automatically recovers by re-examining the target. +# The watchdog is disabled by AT91Bootstrap during normal boot. +# + +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME sama7d6 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # ARM CoreSight JTAG-DP IDCODE + # Version=0x6, Part=0xBA00, Designer=ARM Ltd. + set _CPUTAPID 0x6ba00477 +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + # ARM CoreSight SW-DP DPIDR + set _DAP_TAPID 0x6ba02477 +} + +# +# JTAG or SWD configuration +# +if { [using_jtag] } { + jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID +} else { + swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID +} + +# +# DAP (Debug Access Port) -- required for Cortex-A targets +# +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +# +# Target: Cortex-A7 (single core) +# +set _TARGETNAME $_CHIPNAME.cpu.0 +target create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -endian $_ENDIAN -coreid 0 + +# +# SRAM: 128KB at 0x00100000 +# Used by OpenOCD as work area for flash programming and memory operations. +# +# CAUTION: This SRAM is shared with the ROM code and AT91Bootstrap. +# - During boot: ROM code uses SRAM for bootloader operations +# - After AT91Bootstrap: SRAM contains bootstrap code +# - Set -work-area-backup 1 if you need to preserve SRAM contents +# +$_TARGETNAME configure -work-area-phys 0x00100000 -work-area-size 0x20000 -work-area-backup 0 + +# +# Event handlers +# + +$_TARGETNAME configure -event examine-start { + # Start at conservative speed for reliable initial connection. + adapter speed 1000 +} + +$_TARGETNAME configure -event examine-end { + # Halt CPU immediately to prevent WFI sleep mode + # which can power down debug regions. + # + # Note: This will fail if the ROM code has not yet enabled JTAG. + # JTAG is disabled during ROM code execution and only enabled after: + # - A valid boot image is found and execution jumps to SRAM, OR + # - The SAM-BA Monitor is entered (no valid NVM found) + # Transient errors here are expected and recoverable. + if { [catch { $_TARGETNAME arp_halt }] } { + echo "Warning: Could not halt target." + echo " JTAG may not be enabled yet (ROM code disables it during boot)." + echo " Ensure AT91Bootstrap is flashed, or wait for SAM-BA Monitor entry." + } + catch { $_TARGETNAME arp_waitstate halted 1000 } +} + +$_TARGETNAME configure -event gdb-attach { + # Halt CPU when debugger connects + halt +} + +$_TARGETNAME configure -event gdb-detach { + # Resume CPU when debugger disconnects + resume +} + +$_TARGETNAME configure -event reset-start { + # Reduce speed during reset for stability + adapter speed 1000 +} + +$_TARGETNAME configure -event reset-init { + # Increase speed after reset initialization + adapter speed 4000 +} + +# +# Troubleshooting: +# +# Connection fails immediately after power-on: +# - JTAG is disabled by ROM code during boot +# - On a blank board, wait for SAM-BA Monitor to enable JTAG +# - If AT91Bootstrap is flashed in NVM, JTAG is enabled at SRAM jump +# +# Connection permanently fails: +# - Check OTPC_UHC0R.JTAGDIS fuse -- if non-zero, JTAG is permanently disabled +# - Check OTPC_UHC0R.SECDBG fuse -- if non-zero, secure debug is forbidden +# +# Hardware checks: +# - Ensure JTAGSEL pin is LOW (default with internal pull-down) +# - Ensure TST pin is LOW (must be tied low for normal operation) +# - NTRST (PC22) has internal pull-up (deasserted by default) +# - Verify VDDIN33 power is stable (powers all debug pins PC22-PC26) +# - Use lower adapter speeds (1000 kHz) if experiencing intermittent errors +# - Watchdog resets are normal before AT91Bootstrap disables it +# +# SAM-BA Monitor recovery (when no valid NVM boot image exists): +# - ROM code enters SAM-BA Monitor automatically, enabling JTAG +# - Serial console available at 115200 baud, 8N1 +# - See board configuration file for board-specific USB and UART details +# -- |
|
From: <ge...@op...> - 2026-04-09 14:30:39
|
This is an automated email from Gerrit. "Name of user not set <fre...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9523 -- gerrit commit c63d8abf59a0ca9cfa24cedf0bc241caaf651856 Author: Frederic Boyer <fre...@mi...> Date: Thu Apr 9 16:28:32 2026 +0200 tcl: add SAMA7G5 target and SAMA7G54-EK board configuration Add target configuration for the Microchip SAMA7G5 series (Cortex-A7 based MPU). Supports both JTAG and SWD interfaces. Add board configuration for the SAMA7G54-EK evaluation kit. Link: https://www.microchip.com/en-us/product/sama7g54 Link: https://www.microchip.com/en-us/development-tool/EV21H18A Change-Id: Ieda7658167e87c6f011b4c267d2598b80754e067 Signed-off-by: Frederic Boyer <fre...@mi...> diff --git a/tcl/board/microchip/sama7g54_ek.cfg b/tcl/board/microchip/sama7g54_ek.cfg new file mode 100644 index 0000000000..7e9f03a167 --- /dev/null +++ b/tcl/board/microchip/sama7g54_ek.cfg @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Board configuration for Microchip SAMA7G54-EK evaluation kit +# https://www.microchip.com/en-us/development-tool/EV21H18A +# Datasheet: DS60001765 +# User Guide: DS50003273 +# +# Debug Interface Selection: +# The SAMA7G54-EK has TWO debug paths controlled by jumper J26: +# +# J26 OPEN (factory default): +# - On-board J-Link-OB (ATSAM3U4C) is ENABLED +# - Connect via USB port J24 +# - Provides JTAG + CDC serial (virtual COM port) +# +# J26 CLOSED (this board file's default configuration): +# - On-board J-Link-OB is DISABLED +# - External JTAG/SWD probe connects to 20-pin header J27 +# +# IMPORTANT: J27 is only active when J26 is CLOSED. +# Using J27 with J26 open will NOT work. +# +# IMPORTANT: +# First-time JTAG Connection on blank board (no AT91Bootstrap in NVM): +# 1. Power on the board via J7 (USB Micro-AB) or J1 (DC jack) +# 2. ROM code searches for valid boot media +# 3. No valid code found -> ROM enters SAM-BA Monitor +# 4. SAM-BA Monitor enables JTAG -- OpenOCD can now connect +# To force SAM-BA entry on a board with programmed NVM: +# - Press and hold SW4 (DISABLE_BOOT) during power-on, OR +# - Close jumper J22 to permanently disable on-board boot memories +# - LED D8 RED = boot memories disabled, GREEN = enabled +# - Note: SW4/J22 does NOT disable SD Card boot -- remove card from J4 +# +# Typical Boot sequence (when debugging via JTAG/SWD): +# 1. Load AT91Bootstrap to SRAM (0x00100000) +# - Initializes clocks, DDR, peripherals, disables watchdog +# 2. Load application to DDR (0x60000000) +# - Zephyr, Linux, or bare-metal application +# - DDR must be initialized by AT91Bootstrap first +# +# Reset sources on this board: +# - Power-on reset from MCP16502 PMIC +# - User push button SW2 (Board Reset, connected to NRST) +# - External JTAG/J-Link-OB reset from debug probe +# +# Usage with external probe on J27 (J26 MUST be closed): +# openocd -f interface/jlink.cfg -f board/microchip/sama7g54_ek.cfg +# +# Usage with SWD (external probe): +# openocd -f interface/jlink.cfg -c "transport select swd" \ +# -f board/microchip/sama7g54_ek.cfg + +# Default to JTAG -- silently ignored if already selected +catch { transport select jtag } + +# Target configuration (supports both JTAG and SWD) +source [find target/microchip/sama7g5.cfg] + +# Board-specific adapter speed +# Start at lower speed for reliable initial connection. +# Speed increases to 4 MHz after reset-init event (configured in target file). +adapter speed 1000 + +# Reset configuration for external probe on J27 (J26 closed). +# Both SRST (pin 15/nRST) and TRST (pin 3/NTRST) are available +# on the 20-pin JTAG header. +# NTRST (PC25) has an internal pull-up -- safe to connect. +# +# srst_nogate: SRST is not gated by the JTAG state machine -- +# required because NRST resets the entire chip including debug logic. +# +# For probes with only SRST wired (no TRST), use instead: +# reset_config srst_only srst_nogate +# +reset_config trst_and_srst srst_nogate diff --git a/tcl/target/microchip/sama7g5.cfg b/tcl/target/microchip/sama7g5.cfg new file mode 100644 index 0000000000..411842ab87 --- /dev/null +++ b/tcl/target/microchip/sama7g5.cfg @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Target configuration for Microchip SAMA7G5 series +# +# Cortex-A7 based Microprocessor Unit (MPU) +# https://www.microchip.com/en-us/product/sama7g54 +# Datasheet: DS60001765 +# +# SAMA7G5 series currently includes: +# - SAMA7G54 +# +# Supports both JTAG and SWD transports. +# Select transport before sourcing this file: +# -c "transport select jtag" +# -c "transport select swd" +# If not specified, the adapter driver will auto-select. +# +# IMPORTANT: JTAG/SWD Access Requires ROM Code Completion +# The SAMA7G5 ROM code disables JTAG during boot. +# JTAG is enabled only after one of: +# a) The ROM code finds a valid boot image (e.g., AT91Bootstrap) +# and jumps to SRAM -- JTAG is enabled at that point +# b) No valid NVM found -- ROM code enters SAM-BA Monitor, +# enables USB + UART + JTAG connection +# +# On a blank/fresh board with no NVM programmed: +# - Power on the board +# - Wait for ROM code to enter SAM-BA Monitor +# - JTAG is then enabled automatically +# +# JTAG/Debug Security (OTP Fuses): +# OTPC_UHC0R.JTAGDIS[7:0] = 0x00 (default): JTAG enabled +# OTPC_UHC0R.JTAGDIS[7:0] != 0x00: JTAG permanently disabled +# OTPC_UHC0R.SECDBG[7:0] = 0x00 (default): Secure debug allowed +# OTPC_UHC0R.SECDBG[7:0] != 0x00: Secure debug permanently forbidden +# WARNING: If these OTP fuses are blown, JTAG/SWD is permanently disabled. +# +# Hardware watchdog warning: +# When connecting before AT91Bootstrap runs, the hardware watchdog +# may reset the chip periodically, causing transient DAP errors. +# OpenOCD automatically recovers by re-examining the target. +# The watchdog is disabled by AT91Bootstrap during normal boot. +# + +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME sama7g5 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # ARM CoreSight JTAG-DP IDCODE + # Version=0x6, Part=0xBA00, Designer=ARM Ltd. + set _CPUTAPID 0x6ba00477 +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + # ARM CoreSight SW-DP DPIDR + set _DAP_TAPID 0x6ba02477 +} + +# +# JTAG or SWD configuration +# +if { [using_jtag] } { + jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID +} else { + swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID +} + +# +# DAP (Debug Access Port) -- required for Cortex-A targets +# +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +# +# Target: Cortex-A7 (single core) +# +set _TARGETNAME $_CHIPNAME.cpu.0 +target create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -endian $_ENDIAN -coreid 0 + +# +# SRAM: 128KB at 0x00100000 +# Used by OpenOCD as work area for flash programming and memory operations. +# +# CAUTION: This SRAM is shared with the ROM code and AT91Bootstrap. +# - During boot: ROM code uses SRAM for bootloader operations +# - After AT91Bootstrap: SRAM contains bootstrap code +# - Set -work-area-backup 1 if you need to preserve SRAM contents +# +$_TARGETNAME configure -work-area-phys 0x00100000 -work-area-size 0x20000 -work-area-backup 0 + +# +# Event handlers +# + +$_TARGETNAME configure -event examine-start { + # Start at conservative speed for reliable initial connection. + adapter speed 1000 +} + +$_TARGETNAME configure -event examine-end { + # Halt CPU immediately to prevent WFI sleep mode + # which can power down debug regions. + # + # Note: This will fail if the ROM code has not yet enabled JTAG. + # JTAG is disabled during ROM code execution and only enabled after: + # - A valid boot image is found and execution jumps to SRAM, OR + # - The SAM-BA Monitor is entered (no valid NVM found) + # Transient errors here are expected and recoverable. + if { [catch { $_TARGETNAME arp_halt }] } { + echo "Warning: Could not halt target." + echo " JTAG may not be enabled yet (ROM code disables it during boot)." + echo " Ensure AT91Bootstrap is flashed, or wait for SAM-BA Monitor entry." + } + catch { $_TARGETNAME arp_waitstate halted 1000 } +} + +$_TARGETNAME configure -event gdb-attach { + # Halt CPU when debugger connects + halt +} + +$_TARGETNAME configure -event gdb-detach { + # Resume CPU when debugger disconnects + resume +} + +$_TARGETNAME configure -event reset-start { + # Reduce speed during reset for stability + adapter speed 1000 +} + +$_TARGETNAME configure -event reset-init { + # Increase speed after reset initialization + adapter speed 4000 +} + +# +# Troubleshooting: +# +# Connection fails immediately after power-on: +# - JTAG is disabled by ROM code during boot +# - On a blank board, wait for SAM-BA Monitor to enable JTAG +# - If AT91Bootstrap is flashed in NVM, JTAG is enabled at SRAM jump +# +# Connection permanently fails: +# - Check OTPC_UHC0R.JTAGDIS fuse -- if non-zero, JTAG is permanently disabled +# - Check OTPC_UHC0R.SECDBG fuse -- if non-zero, secure debug is forbidden +# +# Hardware checks: +# - Ensure JTAGSEL pin is LOW (default with internal pull-down) +# - Ensure TST pin is LOW (must be tied low for normal operation) +# - NTRST (PC25) has internal pull-up (deasserted by default) +# - Verify VDDIN33 power is stable (powers all debug pins PC25-PC29) +# - Use lower adapter speeds (1000 kHz) if experiencing intermittent errors +# - Watchdog resets are normal before AT91Bootstrap disables it +# +# SAM-BA Monitor recovery (when no valid NVM boot image exists): +# - ROM code enters SAM-BA Monitor automatically, enabling JTAG +# - Serial console available at 115200 baud, 8N1 +# - See board configuration file for board-specific USB and UART details +# -- |
|
From: <ge...@op...> - 2026-04-09 14:19:29
|
This is an automated email from Gerrit. "Name of user not set <fre...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9522 -- gerrit commit 39aca7146d98a2df61af348ea43094dd8b08369e Author: Frederic Boyer <fre...@mi...> Date: Thu Apr 9 16:18:33 2026 +0200 tcl: add SAMA7G5 target and SAMA7G54-EK board configuration Add target configuration for the Microchip SAMA7G5 series (Cortex-A7 based MPU). Supports both JTAG and SWD interfaces. Add board configuration for the SAMA7G54-EK evaluation kit. Supports J-Link and CMSIS-DAP debug probes via external JTAG header J27 (J26 must be closed). Link: https://www.microchip.com/en-us/product/sama7g54 Link: https://www.microchip.com/en-us/development-tool/EV21H18A Change-Id: I96f3706a76c7322db752b053c9071ed9fa1fc07f Signed-off-by: Frederic Boyer <fre...@mi...> Change-Id: I9e708915354dd2dc4a7c7f0b31b1fcf1ed62735e Signed-off-by: Frederic Boyer <fre...@mi...> diff --git a/tcl/board/microchip/sama7d65_curiosity.cfg b/tcl/board/microchip/sama7d65_curiosity.cfg new file mode 100644 index 0000000000..73d655912d --- /dev/null +++ b/tcl/board/microchip/sama7d65_curiosity.cfg @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Board configuration for Microchip SAMA7D65 Curiosity Board +# https://www.microchip.com/en-us/development-tool/EV63J76A +# Datasheet: DS60001851 +# User Guide: DS50003806 +# +# Debug Interface Selection: +# An external JTAG/SWD probe must be connected to J38. +# + +# +# IMPORTANT: +# First-time JTAG Connection on blank board (no AT91Bootstrap in NVM): +# 1. Power on the board via J3 (USB Type-C) or J1 (DC jack) +# 2. ROM code searches for valid boot media +# 3. No valid code found -> ROM enters SAM-BA Monitor +# 4. SAM-BA Monitor enables JTAG -- OpenOCD can now connect +# To force SAM-BA entry on a board with programmed NVM: +# - Remove JP9 (J36) to disable NAND Flash boot [2] +# - Remove JP10 (J39) to disable QSPI Flash boot [2] +# - Remove any SD card from J10 +# +# Typical Boot sequence (when debugging via JTAG/SWD): +# 1. Load AT91Bootstrap to SRAM (0x00100000) +# - Initializes clocks, DDR, peripherals, disables watchdog +# 2. Load application to DDR (0x60000000) +# - Zephyr, Linux, or bare-metal application +# - DDR must be initialized by AT91Bootstrap first +# +# Reset sources on this board: +# - Power-on reset from MCP16502 PMIC +# - User push button SW4 (Board Reset, connected to NRST) +# - External JTAG probe reset via J38 pin 15 (NRST) +# +# Usage with JTAG (default): +# openocd -f interface/jlink.cfg -f board/microchip/sama7d65_curiosity.cfg +# +# Usage with SWD: +# openocd -f interface/jlink.cfg -c "transport select swd" \ +# -f board/microchip/sama7d65_curiosity.cfg + +# Default to JTAG -- silently ignored if already selected +catch { transport select jtag } + +# Target configuration (supports both JTAG and SWD) +source [find target/microchip/sama7d6.cfg] + +# Board-specific adapter speed +# Start at lower speed for reliable initial connection. +# Speed increases to 4 MHz after reset-init event (configured in target file). +adapter speed 1000 + +# Reset configuration for external probe on J38. +# Both SRST (pin 15/NRST) and TRST (pin 3/NTRST) are available +# on the 20-pin JTAG header. +# NTRST (PC22) has an internal pull-up -- safe to connect. +# +# srst_nogate: SRST is not gated by the JTAG state machine -- +# required because NRST resets the entire chip including debug logic. +# +# For probes with only SRST wired (no TRST), use instead: +# reset_config srst_only srst_nogate +# +reset_config trst_and_srst srst_nogate diff --git a/tcl/target/microchip/sama7d6.cfg b/tcl/target/microchip/sama7d6.cfg new file mode 100644 index 0000000000..650a6e01a1 --- /dev/null +++ b/tcl/target/microchip/sama7d6.cfg @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Target configuration for Microchip SAMA7D6 series +# +# Cortex-A7 based Microprocessor Unit (MPU) +# https://www.microchip.com/en-us/product/sama7d65 +# Datasheet: DS60001851 +# +# SAMA7D6 series currently includes: +# - SAMA7D65 +# +# Supports both JTAG and SWD transports. +# Select transport before sourcing this file: +# -c "transport select jtag" +# -c "transport select swd" +# If not specified, the adapter driver will auto-select. +# +# IMPORTANT: JTAG/SWD Access Requires ROM Code Completion +# The SAMA7D65 ROM code disables JTAG during boot. +# JTAG is enabled only after one of: +# a) The ROM code finds a valid boot image (e.g., AT91Bootstrap) +# and jumps to SRAM -- JTAG is enabled at that point +# b) No valid NVM found -- ROM code enters SAM-BA Monitor, +# enables USB + UART + JTAG connection +# +# On a blank/fresh board with no NVM programmed: +# - Power on the board +# - Wait for ROM code to enter SAM-BA Monitor +# - JTAG is then enabled automatically +# +# JTAG/Debug Security (OTP Fuses): +# OTPC_UHC0R.JTAGDIS[7:0] = 0x00 (default): JTAG enabled +# OTPC_UHC0R.JTAGDIS[7:0] != 0x00: JTAG permanently disabled +# OTPC_UHC0R.SECDBG[7:0] = 0x00 (default): Secure debug allowed +# OTPC_UHC0R.SECDBG[7:0] != 0x00: Secure debug permanently forbidden +# WARNING: If these OTP fuses are blown, JTAG/SWD is permanently disabled. +# +# Hardware watchdog warning: +# When connecting before AT91Bootstrap runs, the hardware watchdog +# may reset the chip periodically, causing transient DAP errors. +# OpenOCD automatically recovers by re-examining the target. +# The watchdog is disabled by AT91Bootstrap during normal boot. +# + +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME sama7d6 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # ARM CoreSight JTAG-DP IDCODE + # Version=0x6, Part=0xBA00, Designer=ARM Ltd. + set _CPUTAPID 0x6ba00477 +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + # ARM CoreSight SW-DP DPIDR + set _DAP_TAPID 0x6ba02477 +} + +# +# JTAG or SWD configuration +# +if { [using_jtag] } { + jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID +} else { + swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID +} + +# +# DAP (Debug Access Port) -- required for Cortex-A targets +# +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +# +# Target: Cortex-A7 (single core) +# +set _TARGETNAME $_CHIPNAME.cpu.0 +target create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -endian $_ENDIAN -coreid 0 + +# +# SRAM: 128KB at 0x00100000 +# Used by OpenOCD as work area for flash programming and memory operations. +# +# CAUTION: This SRAM is shared with the ROM code and AT91Bootstrap. +# - During boot: ROM code uses SRAM for bootloader operations +# - After AT91Bootstrap: SRAM contains bootstrap code +# - Set -work-area-backup 1 if you need to preserve SRAM contents +# +$_TARGETNAME configure -work-area-phys 0x00100000 -work-area-size 0x20000 -work-area-backup 0 + +# +# Event handlers +# + +$_TARGETNAME configure -event examine-start { + # Start at conservative speed for reliable initial connection. + adapter speed 1000 +} + +$_TARGETNAME configure -event examine-end { + # Halt CPU immediately to prevent WFI sleep mode + # which can power down debug regions. + # + # Note: This will fail if the ROM code has not yet enabled JTAG. + # JTAG is disabled during ROM code execution and only enabled after: + # - A valid boot image is found and execution jumps to SRAM, OR + # - The SAM-BA Monitor is entered (no valid NVM found) + # Transient errors here are expected and recoverable. + if { [catch { $_TARGETNAME arp_halt }] } { + echo "Warning: Could not halt target." + echo " JTAG may not be enabled yet (ROM code disables it during boot)." + echo " Ensure AT91Bootstrap is flashed, or wait for SAM-BA Monitor entry." + } + catch { $_TARGETNAME arp_waitstate halted 1000 } +} + +$_TARGETNAME configure -event gdb-attach { + # Halt CPU when debugger connects + halt +} + +$_TARGETNAME configure -event gdb-detach { + # Resume CPU when debugger disconnects + resume +} + +$_TARGETNAME configure -event reset-start { + # Reduce speed during reset for stability + adapter speed 1000 +} + +$_TARGETNAME configure -event reset-init { + # Increase speed after reset initialization + adapter speed 4000 +} + +# +# Troubleshooting: +# +# Connection fails immediately after power-on: +# - JTAG is disabled by ROM code during boot +# - On a blank board, wait for SAM-BA Monitor to enable JTAG +# - If AT91Bootstrap is flashed in NVM, JTAG is enabled at SRAM jump +# +# Connection permanently fails: +# - Check OTPC_UHC0R.JTAGDIS fuse -- if non-zero, JTAG is permanently disabled +# - Check OTPC_UHC0R.SECDBG fuse -- if non-zero, secure debug is forbidden +# +# Hardware checks: +# - Ensure JTAGSEL pin is LOW (default with internal pull-down) +# - Ensure TST pin is LOW (must be tied low for normal operation) +# - NTRST (PC22) has internal pull-up (deasserted by default) +# - Verify VDDIN33 power is stable (powers all debug pins PC22-PC26) +# - Use lower adapter speeds (1000 kHz) if experiencing intermittent errors +# - Watchdog resets are normal before AT91Bootstrap disables it +# +# SAM-BA Monitor recovery (when no valid NVM boot image exists): +# - ROM code enters SAM-BA Monitor automatically, enabling JTAG +# - Serial console available at 115200 baud, 8N1 +# - See board configuration file for board-specific USB and UART details +# -- |
|
From: <ge...@op...> - 2026-04-09 14:19:28
|
This is an automated email from Gerrit. "Name of user not set <fre...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9521 -- gerrit commit 0be69158357b5763d8a93ff908135b8532890a24 Author: Frederic Boyer <fre...@mi...> Date: Thu Apr 9 16:17:28 2026 +0200 tcl: add SAMA7G5 target and SAMA7G54-EK board configuration Add target configuration for the Microchip SAMA7G5 series (Cortex-A7 based MPU). Supports both JTAG and SWD interfaces. Add board configuration for the SAMA7G54-EK evaluation kit. Supports J-Link and CMSIS-DAP debug probes via external JTAG header J27 (J26 must be closed). Link: https://www.microchip.com/en-us/product/sama7g54 Link: https://www.microchip.com/en-us/development-tool/EV21H18A Change-Id: I96f3706a76c7322db752b053c9071ed9fa1fc07f Signed-off-by: Frederic Boyer <fre...@mi...> Change-Id: Ic61c6b5aaa3fd0ab45a696ff5d21001284aee0b0 Signed-off-by: Frederic Boyer <fre...@mi...> diff --git a/tcl/board/microchip/sama7g54_ek.cfg b/tcl/board/microchip/sama7g54_ek.cfg new file mode 100644 index 0000000000..7e9f03a167 --- /dev/null +++ b/tcl/board/microchip/sama7g54_ek.cfg @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Board configuration for Microchip SAMA7G54-EK evaluation kit +# https://www.microchip.com/en-us/development-tool/EV21H18A +# Datasheet: DS60001765 +# User Guide: DS50003273 +# +# Debug Interface Selection: +# The SAMA7G54-EK has TWO debug paths controlled by jumper J26: +# +# J26 OPEN (factory default): +# - On-board J-Link-OB (ATSAM3U4C) is ENABLED +# - Connect via USB port J24 +# - Provides JTAG + CDC serial (virtual COM port) +# +# J26 CLOSED (this board file's default configuration): +# - On-board J-Link-OB is DISABLED +# - External JTAG/SWD probe connects to 20-pin header J27 +# +# IMPORTANT: J27 is only active when J26 is CLOSED. +# Using J27 with J26 open will NOT work. +# +# IMPORTANT: +# First-time JTAG Connection on blank board (no AT91Bootstrap in NVM): +# 1. Power on the board via J7 (USB Micro-AB) or J1 (DC jack) +# 2. ROM code searches for valid boot media +# 3. No valid code found -> ROM enters SAM-BA Monitor +# 4. SAM-BA Monitor enables JTAG -- OpenOCD can now connect +# To force SAM-BA entry on a board with programmed NVM: +# - Press and hold SW4 (DISABLE_BOOT) during power-on, OR +# - Close jumper J22 to permanently disable on-board boot memories +# - LED D8 RED = boot memories disabled, GREEN = enabled +# - Note: SW4/J22 does NOT disable SD Card boot -- remove card from J4 +# +# Typical Boot sequence (when debugging via JTAG/SWD): +# 1. Load AT91Bootstrap to SRAM (0x00100000) +# - Initializes clocks, DDR, peripherals, disables watchdog +# 2. Load application to DDR (0x60000000) +# - Zephyr, Linux, or bare-metal application +# - DDR must be initialized by AT91Bootstrap first +# +# Reset sources on this board: +# - Power-on reset from MCP16502 PMIC +# - User push button SW2 (Board Reset, connected to NRST) +# - External JTAG/J-Link-OB reset from debug probe +# +# Usage with external probe on J27 (J26 MUST be closed): +# openocd -f interface/jlink.cfg -f board/microchip/sama7g54_ek.cfg +# +# Usage with SWD (external probe): +# openocd -f interface/jlink.cfg -c "transport select swd" \ +# -f board/microchip/sama7g54_ek.cfg + +# Default to JTAG -- silently ignored if already selected +catch { transport select jtag } + +# Target configuration (supports both JTAG and SWD) +source [find target/microchip/sama7g5.cfg] + +# Board-specific adapter speed +# Start at lower speed for reliable initial connection. +# Speed increases to 4 MHz after reset-init event (configured in target file). +adapter speed 1000 + +# Reset configuration for external probe on J27 (J26 closed). +# Both SRST (pin 15/nRST) and TRST (pin 3/NTRST) are available +# on the 20-pin JTAG header. +# NTRST (PC25) has an internal pull-up -- safe to connect. +# +# srst_nogate: SRST is not gated by the JTAG state machine -- +# required because NRST resets the entire chip including debug logic. +# +# For probes with only SRST wired (no TRST), use instead: +# reset_config srst_only srst_nogate +# +reset_config trst_and_srst srst_nogate diff --git a/tcl/target/microchip/sama7g5.cfg b/tcl/target/microchip/sama7g5.cfg new file mode 100644 index 0000000000..411842ab87 --- /dev/null +++ b/tcl/target/microchip/sama7g5.cfg @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Target configuration for Microchip SAMA7G5 series +# +# Cortex-A7 based Microprocessor Unit (MPU) +# https://www.microchip.com/en-us/product/sama7g54 +# Datasheet: DS60001765 +# +# SAMA7G5 series currently includes: +# - SAMA7G54 +# +# Supports both JTAG and SWD transports. +# Select transport before sourcing this file: +# -c "transport select jtag" +# -c "transport select swd" +# If not specified, the adapter driver will auto-select. +# +# IMPORTANT: JTAG/SWD Access Requires ROM Code Completion +# The SAMA7G5 ROM code disables JTAG during boot. +# JTAG is enabled only after one of: +# a) The ROM code finds a valid boot image (e.g., AT91Bootstrap) +# and jumps to SRAM -- JTAG is enabled at that point +# b) No valid NVM found -- ROM code enters SAM-BA Monitor, +# enables USB + UART + JTAG connection +# +# On a blank/fresh board with no NVM programmed: +# - Power on the board +# - Wait for ROM code to enter SAM-BA Monitor +# - JTAG is then enabled automatically +# +# JTAG/Debug Security (OTP Fuses): +# OTPC_UHC0R.JTAGDIS[7:0] = 0x00 (default): JTAG enabled +# OTPC_UHC0R.JTAGDIS[7:0] != 0x00: JTAG permanently disabled +# OTPC_UHC0R.SECDBG[7:0] = 0x00 (default): Secure debug allowed +# OTPC_UHC0R.SECDBG[7:0] != 0x00: Secure debug permanently forbidden +# WARNING: If these OTP fuses are blown, JTAG/SWD is permanently disabled. +# +# Hardware watchdog warning: +# When connecting before AT91Bootstrap runs, the hardware watchdog +# may reset the chip periodically, causing transient DAP errors. +# OpenOCD automatically recovers by re-examining the target. +# The watchdog is disabled by AT91Bootstrap during normal boot. +# + +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME sama7g5 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # ARM CoreSight JTAG-DP IDCODE + # Version=0x6, Part=0xBA00, Designer=ARM Ltd. + set _CPUTAPID 0x6ba00477 +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + # ARM CoreSight SW-DP DPIDR + set _DAP_TAPID 0x6ba02477 +} + +# +# JTAG or SWD configuration +# +if { [using_jtag] } { + jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID +} else { + swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID +} + +# +# DAP (Debug Access Port) -- required for Cortex-A targets +# +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +# +# Target: Cortex-A7 (single core) +# +set _TARGETNAME $_CHIPNAME.cpu.0 +target create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -endian $_ENDIAN -coreid 0 + +# +# SRAM: 128KB at 0x00100000 +# Used by OpenOCD as work area for flash programming and memory operations. +# +# CAUTION: This SRAM is shared with the ROM code and AT91Bootstrap. +# - During boot: ROM code uses SRAM for bootloader operations +# - After AT91Bootstrap: SRAM contains bootstrap code +# - Set -work-area-backup 1 if you need to preserve SRAM contents +# +$_TARGETNAME configure -work-area-phys 0x00100000 -work-area-size 0x20000 -work-area-backup 0 + +# +# Event handlers +# + +$_TARGETNAME configure -event examine-start { + # Start at conservative speed for reliable initial connection. + adapter speed 1000 +} + +$_TARGETNAME configure -event examine-end { + # Halt CPU immediately to prevent WFI sleep mode + # which can power down debug regions. + # + # Note: This will fail if the ROM code has not yet enabled JTAG. + # JTAG is disabled during ROM code execution and only enabled after: + # - A valid boot image is found and execution jumps to SRAM, OR + # - The SAM-BA Monitor is entered (no valid NVM found) + # Transient errors here are expected and recoverable. + if { [catch { $_TARGETNAME arp_halt }] } { + echo "Warning: Could not halt target." + echo " JTAG may not be enabled yet (ROM code disables it during boot)." + echo " Ensure AT91Bootstrap is flashed, or wait for SAM-BA Monitor entry." + } + catch { $_TARGETNAME arp_waitstate halted 1000 } +} + +$_TARGETNAME configure -event gdb-attach { + # Halt CPU when debugger connects + halt +} + +$_TARGETNAME configure -event gdb-detach { + # Resume CPU when debugger disconnects + resume +} + +$_TARGETNAME configure -event reset-start { + # Reduce speed during reset for stability + adapter speed 1000 +} + +$_TARGETNAME configure -event reset-init { + # Increase speed after reset initialization + adapter speed 4000 +} + +# +# Troubleshooting: +# +# Connection fails immediately after power-on: +# - JTAG is disabled by ROM code during boot +# - On a blank board, wait for SAM-BA Monitor to enable JTAG +# - If AT91Bootstrap is flashed in NVM, JTAG is enabled at SRAM jump +# +# Connection permanently fails: +# - Check OTPC_UHC0R.JTAGDIS fuse -- if non-zero, JTAG is permanently disabled +# - Check OTPC_UHC0R.SECDBG fuse -- if non-zero, secure debug is forbidden +# +# Hardware checks: +# - Ensure JTAGSEL pin is LOW (default with internal pull-down) +# - Ensure TST pin is LOW (must be tied low for normal operation) +# - NTRST (PC25) has internal pull-up (deasserted by default) +# - Verify VDDIN33 power is stable (powers all debug pins PC25-PC29) +# - Use lower adapter speeds (1000 kHz) if experiencing intermittent errors +# - Watchdog resets are normal before AT91Bootstrap disables it +# +# SAM-BA Monitor recovery (when no valid NVM boot image exists): +# - ROM code enters SAM-BA Monitor automatically, enabling JTAG +# - Serial console available at 115200 baud, 8N1 +# - See board configuration file for board-specific USB and UART details +# -- |
|
From: <ge...@op...> - 2026-04-09 13:11:59
|
This is an automated email from Gerrit. "Name of user not set <fre...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9517 -- gerrit commit 0f027029d22d4ed82c2a0e474215341bf18fed92 Author: Frederic Boyer <fre...@mi...> Date: Thu Apr 9 15:07:30 2026 +0200 tcl/target: add SAMA7G5 target configuration Add target configuration for the Microchip SAMA7G5 series (Cortex-A7 based MPU). Supports both JTAG and SWD interfaces. Work area configured in SRAM for NVM programming and memory operations. Link: https://www.microchip.com/en-us/product/sama7g54 Change-Id: I690ef4cd3edf788f4b04333758f330d053f5d966 Signed-off-by: Frederic Boyer <fre...@mi...> diff --git a/tcl/target/microchip/sama7g5.cfg b/tcl/target/microchip/sama7g5.cfg new file mode 100644 index 0000000000..411842ab87 --- /dev/null +++ b/tcl/target/microchip/sama7g5.cfg @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Target configuration for Microchip SAMA7G5 series +# +# Cortex-A7 based Microprocessor Unit (MPU) +# https://www.microchip.com/en-us/product/sama7g54 +# Datasheet: DS60001765 +# +# SAMA7G5 series currently includes: +# - SAMA7G54 +# +# Supports both JTAG and SWD transports. +# Select transport before sourcing this file: +# -c "transport select jtag" +# -c "transport select swd" +# If not specified, the adapter driver will auto-select. +# +# IMPORTANT: JTAG/SWD Access Requires ROM Code Completion +# The SAMA7G5 ROM code disables JTAG during boot. +# JTAG is enabled only after one of: +# a) The ROM code finds a valid boot image (e.g., AT91Bootstrap) +# and jumps to SRAM -- JTAG is enabled at that point +# b) No valid NVM found -- ROM code enters SAM-BA Monitor, +# enables USB + UART + JTAG connection +# +# On a blank/fresh board with no NVM programmed: +# - Power on the board +# - Wait for ROM code to enter SAM-BA Monitor +# - JTAG is then enabled automatically +# +# JTAG/Debug Security (OTP Fuses): +# OTPC_UHC0R.JTAGDIS[7:0] = 0x00 (default): JTAG enabled +# OTPC_UHC0R.JTAGDIS[7:0] != 0x00: JTAG permanently disabled +# OTPC_UHC0R.SECDBG[7:0] = 0x00 (default): Secure debug allowed +# OTPC_UHC0R.SECDBG[7:0] != 0x00: Secure debug permanently forbidden +# WARNING: If these OTP fuses are blown, JTAG/SWD is permanently disabled. +# +# Hardware watchdog warning: +# When connecting before AT91Bootstrap runs, the hardware watchdog +# may reset the chip periodically, causing transient DAP errors. +# OpenOCD automatically recovers by re-examining the target. +# The watchdog is disabled by AT91Bootstrap during normal boot. +# + +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME sama7g5 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # ARM CoreSight JTAG-DP IDCODE + # Version=0x6, Part=0xBA00, Designer=ARM Ltd. + set _CPUTAPID 0x6ba00477 +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + # ARM CoreSight SW-DP DPIDR + set _DAP_TAPID 0x6ba02477 +} + +# +# JTAG or SWD configuration +# +if { [using_jtag] } { + jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID +} else { + swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID +} + +# +# DAP (Debug Access Port) -- required for Cortex-A targets +# +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +# +# Target: Cortex-A7 (single core) +# +set _TARGETNAME $_CHIPNAME.cpu.0 +target create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -endian $_ENDIAN -coreid 0 + +# +# SRAM: 128KB at 0x00100000 +# Used by OpenOCD as work area for flash programming and memory operations. +# +# CAUTION: This SRAM is shared with the ROM code and AT91Bootstrap. +# - During boot: ROM code uses SRAM for bootloader operations +# - After AT91Bootstrap: SRAM contains bootstrap code +# - Set -work-area-backup 1 if you need to preserve SRAM contents +# +$_TARGETNAME configure -work-area-phys 0x00100000 -work-area-size 0x20000 -work-area-backup 0 + +# +# Event handlers +# + +$_TARGETNAME configure -event examine-start { + # Start at conservative speed for reliable initial connection. + adapter speed 1000 +} + +$_TARGETNAME configure -event examine-end { + # Halt CPU immediately to prevent WFI sleep mode + # which can power down debug regions. + # + # Note: This will fail if the ROM code has not yet enabled JTAG. + # JTAG is disabled during ROM code execution and only enabled after: + # - A valid boot image is found and execution jumps to SRAM, OR + # - The SAM-BA Monitor is entered (no valid NVM found) + # Transient errors here are expected and recoverable. + if { [catch { $_TARGETNAME arp_halt }] } { + echo "Warning: Could not halt target." + echo " JTAG may not be enabled yet (ROM code disables it during boot)." + echo " Ensure AT91Bootstrap is flashed, or wait for SAM-BA Monitor entry." + } + catch { $_TARGETNAME arp_waitstate halted 1000 } +} + +$_TARGETNAME configure -event gdb-attach { + # Halt CPU when debugger connects + halt +} + +$_TARGETNAME configure -event gdb-detach { + # Resume CPU when debugger disconnects + resume +} + +$_TARGETNAME configure -event reset-start { + # Reduce speed during reset for stability + adapter speed 1000 +} + +$_TARGETNAME configure -event reset-init { + # Increase speed after reset initialization + adapter speed 4000 +} + +# +# Troubleshooting: +# +# Connection fails immediately after power-on: +# - JTAG is disabled by ROM code during boot +# - On a blank board, wait for SAM-BA Monitor to enable JTAG +# - If AT91Bootstrap is flashed in NVM, JTAG is enabled at SRAM jump +# +# Connection permanently fails: +# - Check OTPC_UHC0R.JTAGDIS fuse -- if non-zero, JTAG is permanently disabled +# - Check OTPC_UHC0R.SECDBG fuse -- if non-zero, secure debug is forbidden +# +# Hardware checks: +# - Ensure JTAGSEL pin is LOW (default with internal pull-down) +# - Ensure TST pin is LOW (must be tied low for normal operation) +# - NTRST (PC25) has internal pull-up (deasserted by default) +# - Verify VDDIN33 power is stable (powers all debug pins PC25-PC29) +# - Use lower adapter speeds (1000 kHz) if experiencing intermittent errors +# - Watchdog resets are normal before AT91Bootstrap disables it +# +# SAM-BA Monitor recovery (when no valid NVM boot image exists): +# - ROM code enters SAM-BA Monitor automatically, enabling JTAG +# - Serial console available at 115200 baud, 8N1 +# - See board configuration file for board-specific USB and UART details +# -- |
|
From: <ge...@op...> - 2026-04-09 13:11:59
|
This is an automated email from Gerrit. "Name of user not set <fre...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9520 -- gerrit commit 8834ec7efc6db081908e4e2e25b77c83a1905d15 Author: Frederic Boyer <fre...@mi...> Date: Thu Apr 9 15:10:22 2026 +0200 tcl/board: add Microchip SAMA7D65 Curiosity board configuration Add board configuration for the SAMA7D65 Curiosity board. Link: https://www.microchip.com/en-us/development-tool/EV63J76A Change-Id: I5f232a31d0155254fa3589f3bb9f84ff6aa6ba8d Signed-off-by: Frederic Boyer <fre...@mi...> diff --git a/tcl/board/microchip/sama7d65_curiosity.cfg b/tcl/board/microchip/sama7d65_curiosity.cfg new file mode 100644 index 0000000000..ca25bf7f94 --- /dev/null +++ b/tcl/board/microchip/sama7d65_curiosity.cfg @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Board configuration for Microchip SAMA7D65 Curiosity Board +# https://www.microchip.com/en-us/development-tool/EV63J76A +# Datasheet: DS60001851 +# User Guide: DS50003806 +# +# Debug Interface Selection: +# An external JTAG/SWD probe must be connected to J38. +# + +# +# IMPORTANT: +# First-time JTAG Connection on blank board (no AT91Bootstrap in NVM): +# 1. Power on the board via J3 (USB Type-C) or J1 (DC jack) +# 2. ROM code searches for valid boot media +# 3. No valid code found -> ROM enters SAM-BA Monitor +# 4. SAM-BA Monitor enables JTAG -- OpenOCD can now connect +# To force SAM-BA entry on a board with programmed NVM: +# - Remove JP9 (J36) to disable NAND Flash boot [2] +# - Remove JP10 (J39) to disable QSPI Flash boot [2] +# - Remove any SD card from J10 +# +# Typical Boot sequence (when debugging via JTAG/SWD): +# 1. Load AT91Bootstrap to SRAM (0x00100000) +# - Initializes clocks, DDR, peripherals, disables watchdog +# 2. Load application to DDR (0x60000000) +# - Zephyr, Linux, or bare-metal application +# - DDR must be initialized by AT91Bootstrap first +# +# Reset sources on this board: +# - Power-on reset from MCP16502 PMIC +# - User push button SW4 (Board Reset, connected to NRST) +# - External JTAG probe reset via J38 pin 15 (NRST) +# +# Usage with JTAG (default): +# openocd -f interface/jlink.cfg -f board/microchip/sama7d65_curiosity.cfg +# +# Usage with SWD: +# openocd -f interface/jlink.cfg -c "transport select swd" \ +# -f board/microchip/sama7d65_curiosity.cfg + +# Default to JTAG -- silently ignored if already selected +catch { transport select jtag } + +# Target configuration (supports both JTAG and SWD) +source [find target/microchip/sama7d6.cfg] + +# Board-specific adapter speed +# Start at lower speed for reliable initial connection. +# Speed increases to 4 MHz after reset-init event (configured in target file). +adapter speed 1000 + +# Reset configuration for external probe on J38. +# Both SRST (pin 15/NRST) and TRST (pin 3/NTRST) are available +# on the 20-pin JTAG header. +# NTRST (PC22) has an internal pull-up -- safe to connect. +# +# srst_nogate: SRST is not gated by the JTAG state machine -- +# required because NRST resets the entire chip including debug logic. +# +# For probes with only SRST wired (no TRST), use instead: +# reset_config srst_only srst_nogate +# +reset_config trst_and_srst srst_nogate -- |