aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac15
-rw-r--r--contrib/60-openocd.rules2
-rw-r--r--contrib/firmware/angie/c/Makefile7
-rw-r--r--contrib/firmware/angie/c/README4
-rw-r--r--contrib/firmware/angie/c/include/i2c.h28
-rw-r--r--contrib/firmware/angie/c/include/io.h16
-rw-r--r--contrib/firmware/angie/c/include/usb.h120
-rw-r--r--contrib/firmware/angie/c/src/i2c.c127
-rw-r--r--contrib/firmware/angie/c/src/protocol.c13
-rw-r--r--contrib/firmware/angie/c/src/usb.c217
-rw-r--r--contrib/firmware/angie/hdl/Makefile2
-rw-r--r--contrib/firmware/angie/hdl/src/angie_bitstream.ucf (renamed from contrib/firmware/angie/hdl/src/angie_openocd.ucf)16
-rw-r--r--contrib/firmware/angie/hdl/src/angie_bitstream.vhd (renamed from contrib/firmware/angie/hdl/src/angie_openocd.vhd)64
-rw-r--r--doc/openocd.texi73
-rw-r--r--doc/usb_adapters/angie/584e_424e_angie.txt59
-rw-r--r--src/jtag/drivers/Makefile.am3
-rw-r--r--src/jtag/drivers/angie.c12
-rw-r--r--src/jtag/drivers/angie/angie_bitstream.bitbin340702 -> 340704 bytes
-rw-r--r--src/jtag/drivers/angie/angie_firmware.binbin9298 -> 10158 bytes
-rw-r--r--src/jtag/drivers/bcm2835gpio.c3
-rw-r--r--src/jtag/drivers/dmem.c622
-rw-r--r--src/jtag/drivers/stlink_usb.c2
-rw-r--r--src/jtag/interface.h1
-rw-r--r--src/jtag/interfaces.c3
-rw-r--r--src/rtos/zephyr.c1
-rw-r--r--src/target/Makefile.am1
-rw-r--r--src/target/arm.h1
-rw-r--r--src/target/cortex_m.c11
-rw-r--r--src/target/cortex_m.h2
-rw-r--r--src/target/mips32.c58
-rw-r--r--src/target/mips32.h12
-rw-r--r--src/target/mips_cpu.h27
-rw-r--r--src/target/mips_ejtag.c5
-rw-r--r--src/target/mips_m4k.c2
-rw-r--r--tcl/board/ti_am625_swd_native.cfg22
-rw-r--r--tcl/board/ti_am62a7evm.cfg25
-rw-r--r--tcl/board/ti_j721e_swd_native.cfg21
-rw-r--r--tcl/cpu/arc/v2.tcl4
-rw-r--r--tcl/target/rtl872xd.cfg33
-rw-r--r--tcl/target/ti_k3.cfg66
40 files changed, 1552 insertions, 148 deletions
diff --git a/configure.ac b/configure.ac
index 9d851c0..341ee52 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,6 +243,10 @@ AC_ARG_ENABLE([rshim],
AS_HELP_STRING([--enable-rshim], [Enable building the rshim driver]),
[build_rshim=$enableval], [build_rshim=no])
+AC_ARG_ENABLE([dmem],
+ AS_HELP_STRING([--enable-dmem], [Enable building the dmem driver]),
+ [build_dmem=$enableval], [build_dmem=no])
+
m4_define([AC_ARG_ADAPTERS], [
m4_foreach([adapter], [$1],
[AC_ARG_ENABLE(ADAPTER_OPT([adapter]),
@@ -359,6 +363,10 @@ AS_CASE([$host_os],
AC_MSG_ERROR([build_rshim is only available on linux or freebsd])
])
])
+
+ AS_IF([test "x$build_dmem" = "xyes"], [
+ AC_MSG_ERROR([dmem is only available on linux])
+ ])
])
AC_ARG_ENABLE([internal-jimtcl],
@@ -479,6 +487,12 @@ AS_IF([test "x$build_rshim" = "xyes"], [
AC_DEFINE([BUILD_RSHIM], [0], [0 if you don't want to debug BlueField SoC via rshim.])
])
+AS_IF([test "x$build_dmem" = "xyes"], [
+ AC_DEFINE([BUILD_DMEM], [1], [1 if you want to debug via Direct Mem.])
+], [
+ AC_DEFINE([BUILD_DMEM], [0], [0 if you don't want to debug via Direct Mem.])
+])
+
AS_IF([test "x$build_dummy" = "xyes"], [
build_bitbang=yes
AC_DEFINE([BUILD_DUMMY], [1], [1 if you want dummy driver.])
@@ -755,6 +769,7 @@ AM_CONDITIONAL([USE_LIBGPIOD], [test "x$use_libgpiod" = "xyes"])
AM_CONDITIONAL([USE_HIDAPI], [test "x$use_hidapi" = "xyes"])
AM_CONDITIONAL([USE_LIBJAYLINK], [test "x$use_libjaylink" = "xyes"])
AM_CONDITIONAL([RSHIM], [test "x$build_rshim" = "xyes"])
+AM_CONDITIONAL([DMEM], [test "x$build_dmem" = "xyes"])
AM_CONDITIONAL([HAVE_CAPSTONE], [test "x$enable_capstone" != "xno"])
AM_CONDITIONAL([INTERNAL_JIMTCL], [test "x$use_internal_jimtcl" = "xyes"])
diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules
index fd88564..b0e229d 100644
--- a/contrib/60-openocd.rules
+++ b/contrib/60-openocd.rules
@@ -226,6 +226,8 @@ ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1002", MODE="660", GROUP="plugdev",
# ANGIE USB-JTAG Adapter
ATTRS{idVendor}=="584e", ATTRS{idProduct}=="424e", MODE="660", GROUP="plugdev", TAG+="uaccess"
+ATTRS{idVendor}=="584e", ATTRS{idProduct}=="4255", MODE="660", GROUP="plugdev", TAG+="uaccess"
+ATTRS{idVendor}=="584e", ATTRS{idProduct}=="4355", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="584e", ATTRS{idProduct}=="4a55", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Marvell Sheevaplug
diff --git a/contrib/firmware/angie/c/Makefile b/contrib/firmware/angie/c/Makefile
index 80e8cbe..e919cd0 100644
--- a/contrib/firmware/angie/c/Makefile
+++ b/contrib/firmware/angie/c/Makefile
@@ -38,7 +38,7 @@ LDFLAGS = --code-loc 0x0000 --code-size $(CODE_SIZE) --xram-loc $(XRAM_LOC) \
--xram-size $(XRAM_SIZE) --iram-size 256 --model-small
# list of base object files
-OBJECTS = main.rel usb.rel protocol.rel jtag.rel delay.rel USBJmpTb.rel serial.rel gpif.rel
+OBJECTS = main.rel usb.rel protocol.rel jtag.rel delay.rel USBJmpTb.rel serial.rel gpif.rel i2c.rel
HEADERS = $(INCLUDE_DIR)/usb.h \
$(INCLUDE_DIR)/protocol.h \
$(INCLUDE_DIR)/jtag.h \
@@ -47,7 +47,8 @@ HEADERS = $(INCLUDE_DIR)/usb.h \
$(INCLUDE_DIR)/io.h \
$(INCLUDE_DIR)/serial.h \
$(INCLUDE_DIR)/fx2macros.h \
- $(INCLUDE_DIR)/msgtypes.h
+ $(INCLUDE_DIR)/msgtypes.h \
+ $(INCLUDE_DIR)/i2c.h
# Disable all built-in rules.
.SUFFIXES:
@@ -61,7 +62,7 @@ all: angie_firmware.ihx
angie_firmware.ihx: $(OBJECTS)
$(CC) -mmcs51 $(LDFLAGS) -o $@ $^
-# Rebuild every C module (there are only 5 of them) if any header changes.
+# Rebuild every C module (there are only 8 of them) if any header changes.
%.rel: $(SRC_DIR)/%.c $(HEADERS)
$(CC) -c $(CFLAGS) -mmcs51 -I$(INCLUDE_DIR) -o $@ $<
diff --git a/contrib/firmware/angie/c/README b/contrib/firmware/angie/c/README
index 04ed0be..2d41da7 100644
--- a/contrib/firmware/angie/c/README
+++ b/contrib/firmware/angie/c/README
@@ -12,8 +12,8 @@ To compile the firmware, the SDCC compiler package is required. Most Linux
distributions include SDCC in their official package repositories. The SDCC
source code can be found at http://sdcc.sourceforge.net/
-Simply type "make hex" in the ANGIE directory to compile the firmware.
-"make clean" will remove all generated files except the Intel HEX file
+Simply type "make bin" in the ANGIE directory to compile the firmware.
+"make clean" will remove all generated files except the BIN file
required for downloading the firmware to ANGIE.
Note that the EZ-USB FX2 microcontroller does not have on-chip flash,
diff --git a/contrib/firmware/angie/c/include/i2c.h b/contrib/firmware/angie/c/include/i2c.h
new file mode 100644
index 0000000..06185ef
--- /dev/null
+++ b/contrib/firmware/angie/c/include/i2c.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/****************************************************************************
+ File : i2c.h *
+ Contents : i2c bit-bang library *
+ Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. *
+ <aboudjelida@nanoxplore.com> *
+ <ahmederrachedbjld@gmail.com> *
+*****************************************************************************/
+
+#ifndef __I2C_H
+#define __I2C_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+void start_cd(void);
+void repeated_start(void);
+void stop_cd(void);
+void clock_cd(void);
+void send_ack(void);
+bool get_ack(void);
+
+uint8_t get_address(uint8_t adr, uint8_t rdwr);
+
+void send_byte(uint8_t input);
+uint8_t receive_byte(void);
+#endif
diff --git a/contrib/firmware/angie/c/include/io.h b/contrib/firmware/angie/c/include/io.h
index 35afa62..af488f4 100644
--- a/contrib/firmware/angie/c/include/io.h
+++ b/contrib/firmware/angie/c/include/io.h
@@ -45,14 +45,14 @@
#define PIN_TDI IOB3
#define PIN_TDO IOB4
#define PIN_SRST IOB5
-/* PA6 Not Connected */
-/* PA7 Not Connected */
+/* PB6 Not Connected */
+/* PB7 Not Connected */
/* JTAG Signals with direction 'OUT' on port B */
/* PIN_TDI - PIN_TCK - PIN_TMS - PIN_TRST - PIN_SRST */
#define MASK_PORTB_DIRECTION_OUT (bmbit0 | bmbit1 | bmbit2 | bmbit3 | bmbit5)
-/* PORT C */ // Debug:
+/* PORT C */
#define PIN_T0 IOC0
#define PIN_T1 IOC1
#define PIN_T2 IOC2
@@ -62,4 +62,14 @@
/* PC6 Not Connected */
/* PC7 Not Connected */
+/* PORT D */
+#define PIN_SDA IOD0
+#define PIN_SCL IOD1
+#define PIN_SDA_DIR IOD2
+/* PD3 Not Connected */
+/* PD4 Not Connected */
+/* PD5 Not Connected */
+/* PD6 Not Connected */
+/* PD7 Not Connected */
+
#endif
diff --git a/contrib/firmware/angie/c/include/usb.h b/contrib/firmware/angie/c/include/usb.h
index 0450d1d..07cb12a 100644
--- a/contrib/firmware/angie/c/include/usb.h
+++ b/contrib/firmware/angie/c/include/usb.h
@@ -24,18 +24,19 @@
#define STALL_EP0() (EP0CS |= EPSTALL)
#define CLEAR_IRQ() (USBINT = 0)
-/*********** USB descriptors. See section 9.5 of the USB 1.1 spec **********/
+/*********** USB descriptors. See USB 2.0 Spec **********/
-/* USB Descriptor Types. See USB 1.1 spec, page 187, table 9-5 */
-#define DESCRIPTOR_TYPE_DEVICE 0x01
-#define DESCRIPTOR_TYPE_CONFIGURATION 0x02
-#define DESCRIPTOR_TYPE_STRING 0x03
-#define DESCRIPTOR_TYPE_INTERFACE 0x04
-#define DESCRIPTOR_TYPE_ENDPOINT 0x05
+/* USB Descriptor Types. See USB 2.0 Spec */
+#define DESCRIPTOR_TYPE_DEVICE 0x01
+#define DESCRIPTOR_TYPE_CONFIGURATION 0x02
+#define DESCRIPTOR_TYPE_STRING 0x03
+#define DESCRIPTOR_TYPE_INTERFACE 0x04
+#define DESCRIPTOR_TYPE_ENDPOINT 0x05
+#define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0B
#define STR_DESCR(len, ...) { (len) * 2 + 2, DESCRIPTOR_TYPE_STRING, { __VA_ARGS__ } }
-/** USB Device Descriptor. See USB 1.1 spec, pp. 196 - 198 */
+/** USB Device Descriptor. See USB 2.0 Spec */
struct usb_device_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< DEVICE Descriptor Type. */
@@ -53,7 +54,7 @@ struct usb_device_descriptor {
uint8_t bnumconfigurations; /**< Number of possible configurations. */
};
-/** USB Configuration Descriptor. See USB 1.1 spec, pp. 199 - 200 */
+/** USB Configuration Descriptor. See USB 2.0 Spec */
struct usb_config_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< CONFIGURATION descriptor type. */
@@ -65,7 +66,19 @@ struct usb_config_descriptor {
uint8_t maxpower; /**< Maximum power consumption in 2 mA units. */
};
-/** USB Interface Descriptor. See USB 1.1 spec, pp. 201 - 203 */
+/** USB Interface association Descriptor. See USB 2.0 Spec */
+struct usb_interface_association_descriptor {
+ uint8_t blength;
+ uint8_t bdescriptortype;
+ uint8_t bfirstinterface;
+ uint8_t binterfacecount;
+ uint8_t bfunctionclass;
+ uint8_t bfunctionsubclass;
+ uint8_t bfunctionprotocol;
+ uint8_t ifunction;
+};
+
+/** USB Interface Descriptor. See USB 2.0 Spec */
struct usb_interface_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< INTERFACE descriptor type. */
@@ -78,7 +91,7 @@ struct usb_interface_descriptor {
uint8_t iinterface; /**< Index of interface string descriptor. */
};
-/** USB Endpoint Descriptor. See USB 1.1 spec, pp. 203 - 204 */
+/** USB Endpoint Descriptor. See USB 2.0 Spec */
struct usb_endpoint_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< ENDPOINT descriptor type. */
@@ -88,14 +101,14 @@ struct usb_endpoint_descriptor {
uint8_t binterval; /**< Polling interval (in ms) for this endpoint. */
};
-/** USB Language Descriptor. See USB 1.1 spec, pp. 204 - 205 */
+/** USB Language Descriptor. See USB 2.0 Spec */
struct usb_language_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< STRING descriptor type. */
uint16_t wlangid[]; /**< LANGID codes. */
};
-/** USB String Descriptor. See USB 1.1 spec, pp. 204 - 205 */
+/** USB String Descriptor. See USB 2.0 Spec */
struct usb_string_descriptor {
uint8_t blength; /**< Size of this descriptor in bytes. */
uint8_t bdescriptortype; /**< STRING descriptor type. */
@@ -104,7 +117,7 @@ struct usb_string_descriptor {
/********************** USB Control Endpoint 0 related *********************/
-/** USB Control Setup Data. See USB 1.1 spec, pp. 183 - 185 */
+/** USB Control Setup Data. See USB 2.0 Spec */
struct setup_data {
uint8_t bmrequesttype; /**< Characteristics of a request. */
uint8_t brequest; /**< Specific request. */
@@ -121,66 +134,66 @@ extern volatile bool ep1_in;
extern volatile __xdata __at 0xE6B8 struct setup_data setup_data;
/*
- * USB Request Types (bmRequestType): See USB 1.1 spec, page 183, table 9-2
+ * USB Request Types (bmRequestType): See USB 2.0 Spec
*
* Bit 7: Data transfer direction
- * 0 = Host-to-device
- * 1 = Device-to-host
+ * 0 = Host-to-device
+ * 1 = Device-to-host
* Bit 6...5: Type
- * 0 = Standard
- * 1 = Class
- * 2 = Vendor
- * 3 = Reserved
+ * 0 = Standard
+ * 1 = Class
+ * 2 = Vendor
+ * 3 = Reserved
* Bit 4...0: Recipient
- * 0 = Device
- * 1 = Interface
- * 2 = Endpoint
- * 3 = Other
- * 4...31 = Reserved
+ * 0 = Device
+ * 1 = Interface
+ * 2 = Endpoint
+ * 3 = Other
+ * 4...31 = Reserved
*/
-#define USB_DIR_OUT 0x00
-#define USB_DIR_IN 0x80
+#define USB_DIR_OUT 0x00
+#define USB_DIR_IN 0x80
#define USB_REQ_TYPE_STANDARD (0x00 << 5)
#define USB_REQ_TYPE_CLASS (0x01 << 5)
#define USB_REQ_TYPE_VENDOR (0x02 << 5)
#define USB_REQ_TYPE_RESERVED (0x03 << 5)
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
/* Clear Interface Request */
-#define CF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define CF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
#define CF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
#define CF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
/* Get Configuration Request */
-#define GC_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define GC_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Get Descriptor Request */
-#define GD_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define GD_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Get Interface Request */
#define GI_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
/* Get Status Request: See USB 1.1 spec, page 190 */
-#define GS_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define GS_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
#define GS_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
#define GS_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
/* Set Address Request is handled by EZ-USB core */
/* Set Configuration Request */
-#define SC_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define SC_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Set Descriptor Request */
-#define SD_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define SD_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
/* Set Feature Request */
-#define SF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define SF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)
#define SF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)
#define SF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
@@ -190,27 +203,27 @@ extern volatile __xdata __at 0xE6B8 struct setup_data setup_data;
/* Synch Frame Request */
#define SY_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)
-/* USB Requests (bRequest): See USB 1.1 spec, table 9-4 on page 187 */
-#define GET_STATUS 0
-#define CLEAR_FEATURE 1
+/* USB Requests (bRequest): See USB 2.0 Spec */
+#define GET_STATUS 0
+#define CLEAR_FEATURE 1
/* Value '2' is reserved for future use */
-#define SET_FEATURE 3
+#define SET_FEATURE 3
/* Value '4' is reserved for future use */
-#define SET_ADDRESS 5
-#define GET_DESCRIPTOR 6
-#define SET_DESCRIPTOR 7
-#define GET_CONFIGURATION 8
-#define SET_CONFIGURATION 9
+#define SET_ADDRESS 5
+#define GET_DESCRIPTOR 6
+#define SET_DESCRIPTOR 7
+#define GET_CONFIGURATION 8
+#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
#define SYNCH_FRAME 12
-/* Standard Feature Selectors: See USB 1.1 spec, table 9-6 on page 188 */
-#define DEVICE_REMOTE_WAKEUP 1
-#define ENDPOINT_HALT 0
+/* Standard Feature Selectors: See USB 2.0 Spec */
+#define DEVICE_REMOTE_WAKEUP 1
+#define ENDPOINT_HALT 0
/************************** EZ-USB specific stuff **************************/
-/** USB Interrupts. See AN2131-TRM, page 9-4 for details */
+/** USB Interrupts. See EZ-USB FX2-TRM, for details */
enum usb_isr {
SUDAV_ISR = 13,
SOF_ISR,
@@ -265,7 +278,10 @@ bool usb_handle_set_feature(void);
bool usb_handle_get_descriptor(void);
void usb_handle_set_interface(void);
void usb_handle_setup_data(void);
+void usb_handle_i2c_in(void);
+void usb_handle_i2c_out(void);
+void i2c_recieve(void);
void ep_init(void);
void interrupt_init(void);
void io_init(void);
diff --git a/contrib/firmware/angie/c/src/i2c.c b/contrib/firmware/angie/c/src/i2c.c
new file mode 100644
index 0000000..a7004bf
--- /dev/null
+++ b/contrib/firmware/angie/c/src/i2c.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/****************************************************************************
+ File : i2c.cpp *
+ Contents : i2c bit-bang library *
+ Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. *
+ <aboudjelida@nanoxplore.com> *
+ <ahmederrachedbjld@gmail.com> *
+*****************************************************************************/
+
+#include "i2c.h"
+#include "io.h"
+#include "delay.h"
+#include "reg_ezusb.h"
+
+void start_cd(void)
+{
+ PIN_SDA = 0; //SDA = 1;
+ delay_us(1);
+ PIN_SCL = 0; //SCL = 1;
+ delay_us(1);
+}
+
+void repeated_start(void)
+{
+ PIN_SDA = 1;
+ delay_us(1);
+ PIN_SCL = 1;
+ delay_us(1);
+ PIN_SDA = 0;
+ delay_us(1);
+ PIN_SCL = 0;
+ delay_us(1);
+}
+
+void stop_cd(void)
+{
+ PIN_SDA = 0;
+ delay_us(1);
+ PIN_SCL = 1;
+ delay_us(1);
+ PIN_SDA = 1;
+ delay_us(1);
+}
+
+void clock_cd(void)
+{
+ PIN_SCL = 1;
+ delay_us(1);
+ PIN_SCL = 0;
+ delay_us(1);
+}
+
+void send_ack(void)
+{
+ PIN_SDA = 0;
+ delay_us(1);
+ PIN_SCL = 1;
+ delay_us(1);
+ PIN_SCL = 0;
+ delay_us(1);
+}
+
+bool get_ack(void)
+{
+ PIN_SDA_DIR = 1;
+ delay_us(1);
+ OED = 0xFE;
+ PIN_SCL = 1;
+ delay_us(1);
+ bool ack = PIN_SDA;
+ PIN_SCL = 0;
+ delay_us(1);
+ OED = 0xFF;
+ PIN_SDA_DIR = 0;
+ delay_us(1);
+ return ack;
+}
+
+/* here address(8 bits) = adr (7 bits) + type (1 bit) */
+uint8_t get_address(uint8_t adr, uint8_t rdwr)
+{
+ adr &= 0x7F;
+ adr = adr << 1;
+ adr |= (rdwr & 0x01);
+ return adr;
+}
+
+/* here send bit after bit and clocking scl with each bit */
+void send_byte(uint8_t input)
+{
+ for (uint8_t i = 0; i < 8; i++) {
+ if ((input & 0x80)) {
+ PIN_SDA = 1;
+ delay_us(1);
+ clock_cd();
+ } else {
+ PIN_SDA = 0;
+ delay_us(1);
+ clock_cd();
+ }
+ input = input << 1;
+ }
+}
+
+/* here receive bit after bit and clocking scl with each bit */
+
+uint8_t receive_byte(void)
+{
+ PIN_SDA_DIR = 1; //FX2 <-- FPGA
+ OED = 0xFE;
+ uint8_t input = 0x00;
+ for (uint8_t i = 0; i < 8; i++) {
+ PIN_SCL = 1;
+ delay_us(1);
+ input = input << 1;
+ if (PIN_SDA == 1)
+ input |= 0x01;
+ else
+ input |= 0X00;
+
+ PIN_SCL = 0;
+ delay_us(1);
+ }
+ OED = 0xFF;
+ PIN_SDA_DIR = 0;
+ return input;
+}
diff --git a/contrib/firmware/angie/c/src/protocol.c b/contrib/firmware/angie/c/src/protocol.c
index 3f3aaaf..d84534b 100644
--- a/contrib/firmware/angie/c/src/protocol.c
+++ b/contrib/firmware/angie/c/src/protocol.c
@@ -139,15 +139,12 @@ bool execute_command(void)
payload_index_in += usb_in_bytecount;
/* Determine if this was the last command */
- if ((cmd_id_index + usb_out_bytecount + 1) >= EP1OUTBC) {
+ if ((cmd_id_index + usb_out_bytecount + 1) >= EP1OUTBC)
return true;
- /* Line between return and else required by checkpatch: */
- uint8_t a = 0;
- } else {
- /* Not the last command, update cmd_id_index */
- cmd_id_index += (usb_out_bytecount + 1);
- return false;
- }
+
+ /* Not the last command, update cmd_id_index */
+ cmd_id_index += (usb_out_bytecount + 1);
+ return false;
}
/**
diff --git a/contrib/firmware/angie/c/src/usb.c b/contrib/firmware/angie/c/src/usb.c
index 8fd4de6..747fef1 100644
--- a/contrib/firmware/angie/c/src/usb.c
+++ b/contrib/firmware/angie/c/src/usb.c
@@ -18,6 +18,7 @@
#include <fx2macros.h>
#include <serial.h>
#include <stdio.h>
+#include "i2c.h"
/* Also update external declarations in "include/usb.h" if making changes to
* these variables!
@@ -36,9 +37,9 @@ __code struct usb_device_descriptor device_descriptor = {
.blength = sizeof(struct usb_device_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_DEVICE,
.bcdusb = 0x0200, /* BCD: 02.00 (Version 2.0 USB spec) */
- .bdeviceclass = 0xFF, /* 0xFF = vendor-specific */
- .bdevicesubclass = 0xFF,
- .bdeviceprotocol = 0xFF,
+ .bdeviceclass = 0xEF,
+ .bdevicesubclass = 0x02,
+ .bdeviceprotocol = 0x01,
.bmaxpacketsize0 = 64,
.idvendor = 0x584e,
.idproduct = 0x424e,
@@ -55,25 +56,36 @@ __code struct usb_config_descriptor config_descriptor = {
.blength = sizeof(struct usb_config_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_CONFIGURATION,
.wtotallength = sizeof(struct usb_config_descriptor) +
- sizeof(struct usb_interface_descriptor) +
- (NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)),
- .bnuminterfaces = 1,
+ 3 * sizeof(struct usb_interface_descriptor) +
+ ((NUM_ENDPOINTS + 2) * sizeof(struct usb_endpoint_descriptor)),
+ .bnuminterfaces = 2,
.bconfigurationvalue = 1,
- .iconfiguration = 4, /* String describing this configuration */
+ .iconfiguration = 1, /* String describing this configuration */
.bmattributes = 0x80, /* Only MSB set according to USB spec */
.maxpower = 50 /* 100 mA */
};
+__code struct usb_interface_association_descriptor interface_association_descriptor = {
+ .blength = sizeof(struct usb_interface_association_descriptor),
+ .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,
+ .bfirstinterface = 0x01,
+ .binterfacecount = 0x02,
+ .bfunctionclass = 0x02,
+ .bfunctionsubclass = 0x00,
+ .bfunctionprotocol = 0x00,
+ .ifunction = 0x00
+};
+
__code struct usb_interface_descriptor interface_descriptor00 = {
.blength = sizeof(struct usb_interface_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
.binterfacenumber = 0,
.balternatesetting = 0,
.bnumendpoints = NUM_ENDPOINTS,
- .binterfaceclass = 0xFF,
- .binterfacesubclass = 0xFF,
- .binterfaceprotocol = 0xFF,
- .iinterface = 0
+ .binterfaceclass = 0XFF,
+ .binterfacesubclass = 0x00,
+ .binterfaceprotocol = 0x00,
+ .iinterface = 4
};
__code struct usb_endpoint_descriptor bulk_ep1_out_endpoint_descriptor = {
@@ -103,16 +115,19 @@ __code struct usb_endpoint_descriptor bulk_ep2_endpoint_descriptor = {
.binterval = 0
};
-__code struct usb_endpoint_descriptor bulk_ep4_endpoint_descriptor = {
- .blength = sizeof(struct usb_endpoint_descriptor),
- .bdescriptortype = 0x05,
- .bendpointaddress = (4 | USB_DIR_IN),
- .bmattributes = 0x02,
- .wmaxpacketsize = 512,
- .binterval = 0
+__code struct usb_interface_descriptor interface_descriptor01 = {
+ .blength = sizeof(struct usb_interface_descriptor),
+ .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
+ .binterfacenumber = 1,
+ .balternatesetting = 0,
+ .bnumendpoints = 2,
+ .binterfaceclass = 0x0A,
+ .binterfacesubclass = 0x00,
+ .binterfaceprotocol = 0x00,
+ .iinterface = 0x00
};
-__code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = {
+__code struct usb_endpoint_descriptor bulk_ep6_out_endpoint_descriptor = {
.blength = sizeof(struct usb_endpoint_descriptor),
.bdescriptortype = 0x05,
.bendpointaddress = (6 | USB_DIR_OUT),
@@ -121,19 +136,18 @@ __code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = {
.binterval = 0
};
-__code struct usb_endpoint_descriptor bulk_ep8_endpoint_descriptor = {
+__code struct usb_endpoint_descriptor bulk_ep8_in_endpoint_descriptor = {
.blength = sizeof(struct usb_endpoint_descriptor),
.bdescriptortype = 0x05,
- .bendpointaddress = (8 | USB_DIR_OUT),
+ .bendpointaddress = (8 | USB_DIR_IN),
.bmattributes = 0x02,
.wmaxpacketsize = 512,
.binterval = 0
};
-
__code struct usb_language_descriptor language_descriptor = {
.blength = 4,
.bdescriptortype = DESCRIPTOR_TYPE_STRING,
- .wlangid = {0x0409 /* US English */}
+ .wlangid = {0x0409} /* US English */
};
__code struct usb_string_descriptor strmanufacturer =
@@ -212,9 +226,15 @@ void ep4_isr(void)__interrupt EP4_ISR
}
void ep6_isr(void)__interrupt EP6_ISR
{
+ i2c_recieve();
+ EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
+ EPIRQ = 0x40; /* Clear individual EP6OUT IRQ */
+
}
void ep8_isr(void)__interrupt EP8_ISR
{
+ EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
+ EPIRQ = 0x80; /* Clear individual EP8IN IRQ */
}
void ibn_isr(void)__interrupt IBN_ISR
{
@@ -411,21 +431,21 @@ bool usb_handle_clear_feature(void)
switch (setup_data.bmrequesttype) {
case CF_DEVICE:
/* Clear remote wakeup not supported: stall EP0 */
- STALL_EP0();
- break;
+ STALL_EP0();
+ break;
case CF_ENDPOINT:
- if (setup_data.wvalue == 0) {
+ if (setup_data.wvalue == 0) {
/* Unstall the endpoint specified in wIndex */
- ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
- if (!ep_cs)
- return false;
- *ep_cs &= ~EPSTALL;
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
+ if (!ep_cs)
+ return false;
+ *ep_cs &= ~EPSTALL;
} else {
/* Unsupported feature, stall EP0 */
- STALL_EP0();
- }
- break;
- default:
+ STALL_EP0();
+ }
+ break;
+ default:
/* Vendor commands... */
break;
}
@@ -597,7 +617,6 @@ bool usb_handle_send_bitstream(void)
/* wait until GPIF transaction has been completed */
while ((GPIFTRIG & BMGPIFDONE) == 0) {
if (ix-- == 0) {
- printf("GPIF done time out\n");
break;
}
delay_ms(1);
@@ -697,9 +716,9 @@ void ep_init(void)
syncdelay(3);
EP4CFG = 0x00;
syncdelay(3);
- EP6CFG = 0x00;
+ EP6CFG = 0xA2;
syncdelay(3);
- EP8CFG = 0x00;
+ EP8CFG = 0xE2;
syncdelay(3);
/* arm EP1-OUT */
@@ -714,6 +733,12 @@ void ep_init(void)
EP1INBC = 0;
syncdelay(3);
+ /* arm EP6-OUT */
+ EP6BCL = 0x80;
+ syncdelay(3);
+ EP6BCL = 0x80;
+ syncdelay(3);
+
/* Standard procedure to reset FIFOs */
FIFORESET = BMNAKALL; /* NAK all transfers during the reset */
syncdelay(3);
@@ -727,9 +752,110 @@ void ep_init(void)
syncdelay(3);
}
+void i2c_recieve(void)
+{
+ PIN_SDA_DIR = 0;
+ if (EP6FIFOBUF[0] == 1) {
+ uint8_t rdwr = EP6FIFOBUF[0]; //read
+ uint8_t reg_adr_check = EP6FIFOBUF[1];
+ uint8_t count = EP6FIFOBUF[2]; //request data count
+ uint8_t adr = EP6FIFOBUF[3]; //address
+ uint8_t reg_adr = EP6FIFOBUF[4];
+ uint8_t address = get_address(adr, rdwr); //address byte (read command)
+ uint8_t address_2 = get_address(adr, 0); //address byte 2 (write command)
+
+ printf("%d\n", address);
+
+ /* start: */
+ start_cd();
+ /* address: */
+ send_byte(address_2); //write
+ /* ack: */
+ uint8_t ack = get_ack();
+
+ delay_us(10);
+
+ /* send data */
+ if (reg_adr_check) { //if there is a byte reg
+ send_byte(reg_adr);
+ /* ack(): */
+ ack = get_ack();
+ }
+
+ delay_us(10);
+
+ /* repeated start: */
+ repeated_start();
+ /* address: */
+ send_byte(address);
+ /* get ack: */
+ ack = get_ack();
+
+ delay_us(10);
+
+ /* receive data */
+ for (uint8_t i = 0; i < count; i++) {
+ EP8FIFOBUF[i] = receive_byte();
+
+ /* send ack: */
+ send_ack();
+ }
+
+ delay_ms(1);
+
+ /* stop */
+ stop_cd();
+
+ delay_us(10);
+
+ EP8BCH = 0; //EP8
+ syncdelay(3);
+ EP8BCL = count; //EP8
+
+ EP6BCL = 0x80; //EP6
+ syncdelay(3);
+ EP6BCL = 0x80; //EP6
+ } else {
+ uint8_t rdwr = EP6FIFOBUF[0]; //write
+ uint8_t count = EP6FIFOBUF[1]; //data count
+ uint8_t adr = EP6FIFOBUF[2]; //address
+ uint8_t address = get_address(adr, rdwr); //address byte (read command)
+ uint8_t ack_cnt = 0;
+
+/* start(): */
+ start_cd();
+/* address: */
+ send_byte(address); //write
+/* ack(): */
+ if (!get_ack())
+ ack_cnt++;
+/* send data */
+ for (uint8_t i = 0; i < count; i++) {
+ send_byte(EP6FIFOBUF[i + 3]);
+
+ /* get ack: */
+ if (!get_ack())
+ ack_cnt++;
+ }
+
+/* stop */
+ stop_cd();
+
+ EP8FIFOBUF[0] = ack_cnt;
+
+ EP8BCH = 0; //EP8
+ syncdelay(3);
+ EP8BCL = 1; //EP8
+
+ EP6BCL = 0x80; //EP6
+ syncdelay(3);
+ EP6BCL = 0x80; //EP6
+ }
+}
+
/**
* Interrupt initialization. Configures USB interrupts.
- */
+ **/
void interrupt_init(void)
{
/* Enable Interrupts */
@@ -742,11 +868,11 @@ void interrupt_init(void)
/* Enable INT 2 & 4 Autovectoring */
INTSETUP |= (AV2EN | AV4EN);
- /* Enable individual EP1OUT&IN interrupts */
- EPIE |= 0x0C;
+ /* Enable individual EP1OUT&IN & EP6&8 interrupts */
+ EPIE |= 0xCC;
/* Clear individual USB interrupt IRQ */
- EPIRQ = 0x0C;
+ EPIRQ = 0xCC;
/* Enable SUDAV interrupt */
USBIEN |= SUDAVI;
@@ -777,8 +903,15 @@ void io_init(void)
PIN_TDI = 0;
PIN_SRST = 1;
+
+
/* PORT C */
PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */
- OEC = 0xEF;
+ OEC = 0xFF;
IOC = 0xFF;
+
+ /* PORT D */
+ OED = 0xFF;
+ IOD = 0xFF;
+ PIN_SDA_DIR = 0;
}
diff --git a/contrib/firmware/angie/hdl/Makefile b/contrib/firmware/angie/hdl/Makefile
index c2c74a0..b28b650 100644
--- a/contrib/firmware/angie/hdl/Makefile
+++ b/contrib/firmware/angie/hdl/Makefile
@@ -2,7 +2,7 @@
# Copyright (C) 2023 by NanoXplore, France - all rights reserved
# Needed by timing test
-export PROJECT := angie_openocd
+export PROJECT := angie_bitstream
TARGET_PART := xc6slx9-2tqg144
export TOPLEVEL := S609
diff --git a/contrib/firmware/angie/hdl/src/angie_openocd.ucf b/contrib/firmware/angie/hdl/src/angie_bitstream.ucf
index fda3cda..92a89c9 100644
--- a/contrib/firmware/angie/hdl/src/angie_openocd.ucf
+++ b/contrib/firmware/angie/hdl/src/angie_bitstream.ucf
@@ -14,17 +14,31 @@ net TRST LOC = 'P48' ;
net TMS LOC = 'P43' ;
net TCK LOC = 'P44' ;
net TDI LOC = 'P45' ;
-net TDO LOC = 'P46' ;
+net TDO LOC = 'P46' ;
net SRST LOC = 'P61' ;
+
+net SDA LOC = 'P50' ;
+net SCL LOC = 'P51' ;
+net SDA_DIR LOC = 'P56' ;
+
net SI_TDO LOC = 'P16' ;
net SO_TRST LOC = 'P32' ;
net SO_TMS LOC = 'P27' ;
net SO_TCK LOC = 'P30' ;
net SO_TDI LOC = 'P26' ;
net SO_SRST LOC = 'P12' ;
+
+net SO_SDA_OUT LOC = 'P140' ;
+net SO_SDA_IN LOC = 'P1' ;
+net SO_SCL LOC = 'P137';
+
net ST_0 LOC = 'P29' ;
net ST_1 LOC = 'P21' ;
net ST_2 LOC = 'P11' ;
+
+net ST_4 LOC = 'P134' ;
+net ST_5 LOC = 'P139' ;
+
net FTP<0> LOC = 'P121' ;
net FTP<1> LOC = 'P120' ;
net FTP<2> LOC = 'P119' ;
diff --git a/contrib/firmware/angie/hdl/src/angie_openocd.vhd b/contrib/firmware/angie/hdl/src/angie_bitstream.vhd
index d79c0fe..21ddb84 100644
--- a/contrib/firmware/angie/hdl/src/angie_openocd.vhd
+++ b/contrib/firmware/angie/hdl/src/angie_bitstream.vhd
@@ -16,22 +16,35 @@ library UNISIM;
use UNISIM.VComponents.all;
entity S609 is port(
- TRST : in std_logic;
- TMS : in std_logic;
- TCK : in std_logic;
- TDI : in std_logic;
- TDO : out std_logic;
- SRST : in std_logic;
- FTP : out std_logic_vector(7 downto 0); -- Test points
+ TRST : in std_logic;
+ TMS : in std_logic;
+ TCK : in std_logic;
+ TDI : in std_logic;
+ TDO : out std_logic;
+ SRST : in std_logic;
+
+ SDA : inout std_logic;
+ SDA_DIR : in std_logic;
+ SCL : in std_logic;
+
+ FTP : out std_logic_vector(7 downto 0):=(others => '1'); -- Test points
SI_TDO : in std_logic;
- ST_0 : out std_logic;
- ST_1 : out std_logic;
- ST_2 : out std_logic;
+ ST_0 : out std_logic;
+ ST_1 : out std_logic;
+ ST_2 : out std_logic;
+
+ ST_4 : out std_logic;
+ ST_5 : out std_logic;
+
+ SO_SDA_OUT : out std_logic;
+ SO_SDA_IN : in std_logic;
+ SO_SCL : out std_logic;
+
SO_TRST : out std_logic;
- SO_TMS : out std_logic;
- SO_TCK : out std_logic;
+ SO_TMS : out std_logic;
+ SO_TCK : out std_logic;
SO_TDI : out std_logic;
- SO_SRST :out std_logic
+ SO_SRST : out std_logic
);
end S609;
@@ -42,6 +55,8 @@ begin
ST_0 <= '0';
ST_1 <= '1';
+ST_4 <= '0';
+
--TDO:
TDO <= not SI_TDO;
@@ -53,11 +68,26 @@ SO_TDI <= TDI;
ST_2 <= SRST;
SO_SRST <= '0';
+SO_SCL <= SCL;
+
+SDA <= not(SO_SDA_IN) when (SDA_DIR = '1') else 'Z';
+SO_SDA_OUT <= SDA;
+
+process(SDA_DIR)
+begin
+ if(SDA_DIR = '1') then
+ ST_5 <= '1';
+ else
+ ST_5 <= '0';
+ end if;
+end process;
+
+
--Points de test:
-FTP(0) <= TRST;
-FTP(1) <= TMS;
-FTP(2) <= TCK;
-FTP(3) <= TDI;
+FTP(0) <= SDA;
+FTP(1) <= SCL;
+FTP(2) <= not(SO_SDA_IN);
+FTP(3) <= SDA_DIR;
FTP(5) <= SRST;
FTP(4) <= SI_TDO;
FTP(6) <= '1';
diff --git a/doc/openocd.texi b/doc/openocd.texi
index c8a42f4..a2dacf2 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -3597,6 +3597,79 @@ espusbjtag chip_id 1
@end deffn
+@deffn {Interface Driver} {dmem} Direct Memory access debug interface
+
+The Texas Instruments K3 SoC family provides memory access to DAP
+and coresight control registers. This allows control over the
+microcontrollers directly from one of the processors on the SOC
+itself.
+
+For maximum performance, the driver accesses the debug registers
+directly over the SoC memory map. The memory mapping requires read
+and write permission to kernel memory via "/dev/mem" and assumes that
+the system firewall configurations permit direct access to the debug
+memory space.
+
+@verbatim
++-----------+
+| OpenOCD | SoC mem map (/dev/mem)
+| on +--------------+
+| Cortex-A53| |
++-----------+ |
+ |
++-----------+ +-----v-----+
+|Cortex-M4F <--------+ |
++-----------+ | |
+ | DebugSS |
++-----------+ | |
+|Cortex-M4F <--------+ |
++-----------+ +-----------+
+@end verbatim
+
+NOTE: Firewalls are configurable in K3 SoC and depending on various types of
+device configuration, this function may be blocked out. Typical behavior
+observed in such cases is a firewall exception report on the security
+controller and armv8 processor reporting a system error.
+
+See @file{tcl/interface/ti_k3_am625-swd-native.cfg} for a sample configuration
+file.
+
+@deffn {Command} {dmem info}
+Print the DAPBUS dmem configuration.
+@end deffn
+
+@deffn {Config Command} {dmem device} device_path
+Set the DAPBUS memory access device (default: /dev/mem).
+@end deffn
+
+@deffn {Config Command} {dmem base_address} base_address
+Set the DAPBUS base address which is used to access CoreSight
+compliant Access Ports (APs) directly.
+@end deffn
+
+@deffn {Config Command} {dmem ap_address_offset} offset_address
+Set the address offset between Access Ports (APs).
+@end deffn
+
+@deffn {Config Command} {dmem max_aps} n
+Set the maximum number of valid access ports on the SoC.
+@end deffn
+
+@deffn {Config Command} {dmem emu_ap_list} n
+Set the list of Access Ports (APs) that need to be emulated. This
+emulation mode supports software translation of an AP request into an
+address mapped transaction that does not rely on physical AP hardware.
+This maybe needed if the AP is either denied access via memory map or
+protected using other SoC mechanisms.
+@end deffn
+
+@deffn {Config Command} {dmem emu_base_address_range} base_address address_window_size
+Set the emulated address and address window size. Both of these
+parameters must be aligned to page size.
+@end deffn
+
+@end deffn
+
@section Transport Configuration
@cindex Transport
As noted earlier, depending on the version of OpenOCD you use,
diff --git a/doc/usb_adapters/angie/584e_424e_angie.txt b/doc/usb_adapters/angie/584e_424e_angie.txt
index 8162cba..d68657a 100644
--- a/doc/usb_adapters/angie/584e_424e_angie.txt
+++ b/doc/usb_adapters/angie/584e_424e_angie.txt
@@ -1,13 +1,13 @@
# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later
-Bus 001 Device 056: ID 584e:424e NanoXplore, SAS. ANGIE Adapter
+Bus 001 Device 029: ID 584e:424e NanoXplore, SAS. ANGIE Adapter
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
- bDeviceClass 255 Vendor Specific Class
- bDeviceSubClass 255 Vendor Specific Subclass
- bDeviceProtocol 255 Vendor Specific Protocol
+ bDeviceClass 239 Miscellaneous Device
+ bDeviceSubClass 2
+ bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x584e
idProduct 0x424e
@@ -19,13 +19,22 @@ Device Descriptor:
Configuration Descriptor:
bLength 9
bDescriptorType 2
- wTotalLength 0x0027
- bNumInterfaces 1
+ wTotalLength 0x0047
+ bNumInterfaces 2
bConfigurationValue 1
- iConfiguration 4 (error)
+ iConfiguration 1 NanoXplore, SAS.
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
+ Interface Association:
+ bLength 8
+ bDescriptorType 11
+ bFirstInterface 1
+ bInterfaceCount 2
+ bFunctionClass 2 Communications
+ bFunctionSubClass 0
+ bFunctionProtocol 0
+ iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
@@ -33,9 +42,9 @@ Device Descriptor:
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
- bInterfaceSubClass 255 Vendor Specific Subclass
- bInterfaceProtocol 255 Vendor Specific Protocol
- iInterface 0
+ bInterfaceSubClass 0
+ bInterfaceProtocol 0
+ iInterface 4 JTAG Adapter
Endpoint Descriptor:
bLength 7
bDescriptorType 5
@@ -66,3 +75,33 @@ Device Descriptor:
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 1
+ bAlternateSetting 0
+ bNumEndpoints 2
+ bInterfaceClass 10 CDC Data
+ bInterfaceSubClass 0
+ bInterfaceProtocol 0
+ iInterface 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x06 EP 6 OUT
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0200 1x 512 bytes
+ bInterval 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x88 EP 8 IN
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0200 1x 512 bytes
+ bInterval 0
diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
index 4b2dbc4..e404afe 100644
--- a/src/jtag/drivers/Makefile.am
+++ b/src/jtag/drivers/Makefile.am
@@ -161,6 +161,9 @@ endif
if RSHIM
DRIVERFILES += %D%/rshim.c
endif
+if DMEM
+DRIVERFILES += %D%/dmem.c
+endif
if OSBDM
DRIVERFILES += %D%/osbdm.c
endif
diff --git a/src/jtag/drivers/angie.c b/src/jtag/drivers/angie.c
index 35811fb..9cc0865 100644
--- a/src/jtag/drivers/angie.c
+++ b/src/jtag/drivers/angie.c
@@ -30,8 +30,10 @@
/** USB Product ID of ANGIE device in unconfigured state (no firmware loaded
* yet) or with its firmware. */
-#define ANGIE_PID 0x424e
-#define ANGIE_PID_2 0x4a55
+#define ANGIE_PID 0x424e
+#define ANGIE_PID_2 0x4255
+#define ANGIE_PID_3 0x4355
+#define ANGIE_PID_4 0x4a55
/** Address of EZ-USB ANGIE CPU Control & Status register. This register can be
* written by issuing a Control EP0 vendor request. */
@@ -252,8 +254,8 @@ static struct angie *angie_handle;
static int angie_usb_open(struct angie *device)
{
struct libusb_device_handle *usb_device_handle;
- const uint16_t vids[] = {ANGIE_VID, ANGIE_VID, 0};
- const uint16_t pids[] = {ANGIE_PID, ANGIE_PID_2, 0};
+ const uint16_t vids[] = {ANGIE_VID, ANGIE_VID, ANGIE_VID, ANGIE_VID, 0};
+ const uint16_t pids[] = {ANGIE_PID, ANGIE_PID_2, ANGIE_PID_3, ANGIE_PID_4, 0};
int ret = jtag_libusb_open(vids, pids, &usb_device_handle, NULL);
@@ -1719,6 +1721,8 @@ static int angie_reset(int trst, int srst)
high |= SIGNAL_SRST;
int ret = angie_append_set_signals_cmd(device, low, high);
+ if (ret == ERROR_OK)
+ angie_clear_queue(device);
ret = angie_execute_queued_commands(device, LIBUSB_TIMEOUT_MS);
if (ret == ERROR_OK)
diff --git a/src/jtag/drivers/angie/angie_bitstream.bit b/src/jtag/drivers/angie/angie_bitstream.bit
index 9e83e6b..aebd370 100644
--- a/src/jtag/drivers/angie/angie_bitstream.bit
+++ b/src/jtag/drivers/angie/angie_bitstream.bit
Binary files differ
diff --git a/src/jtag/drivers/angie/angie_firmware.bin b/src/jtag/drivers/angie/angie_firmware.bin
index 38f81c4..da69631 100644
--- a/src/jtag/drivers/angie/angie_firmware.bin
+++ b/src/jtag/drivers/angie/angie_firmware.bin
Binary files differ
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
index 39e4af3..f41f7b5 100644
--- a/src/jtag/drivers/bcm2835gpio.c
+++ b/src/jtag/drivers/bcm2835gpio.c
@@ -167,7 +167,8 @@ static void initialize_gpio(enum adapter_gpio_config_index idx)
}
/* Direction for non push-pull is already set by set_gpio_value() */
- if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL)
+ if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
+ && adapter_gpio_config[idx].init_state != ADAPTER_GPIO_INIT_STATE_INPUT)
OUT_GPIO(adapter_gpio_config[idx].gpio_num);
bcm2835_gpio_synchronize();
}
diff --git a/src/jtag/drivers/dmem.c b/src/jtag/drivers/dmem.c
new file mode 100644
index 0000000..4dc5821
--- /dev/null
+++ b/src/jtag/drivers/dmem.c
@@ -0,0 +1,622 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ */
+
+/**
+ * @file
+ * This file implements support for the Direct memory access to CoreSight
+ * Access Ports (APs) or emulate the same to access CoreSight debug registers
+ * directly.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/mman.h>
+
+#include <helper/align.h>
+#include <helper/types.h>
+#include <helper/system.h>
+#include <helper/time_support.h>
+#include <helper/list.h>
+#include <jtag/interface.h>
+
+#include <target/arm_adi_v5.h>
+#include <transport/transport.h>
+
+struct dmem_emu_ap_info {
+ uint64_t ap_num;
+ /* Emulation mode AP state variables */
+ uint32_t apbap_tar;
+ uint32_t apbap_csw;
+};
+
+/*
+ * This bit tells if the transaction is coming in from jtag or not
+ * we just mask this out to emulate direct address access
+ */
+#define ARM_APB_PADDR31 BIT(31)
+
+static void *dmem_map_base, *dmem_virt_base_addr;
+static size_t dmem_mapped_size;
+
+/* Default dmem device. */
+#define DMEM_DEV_PATH_DEFAULT "/dev/mem"
+static char *dmem_dev_path;
+static uint64_t dmem_dap_base_address;
+static unsigned int dmem_dap_max_aps = 1;
+static uint32_t dmem_dap_ap_offset = 0x100;
+
+/* DAP error code. */
+static int dmem_dap_retval = ERROR_OK;
+
+/* AP Emulation Mode */
+static uint64_t dmem_emu_base_address;
+static uint64_t dmem_emu_size;
+static void *dmem_emu_map_base, *dmem_emu_virt_base_addr;
+static size_t dmem_emu_mapped_size;
+#define DMEM_MAX_EMULATE_APS 5
+static unsigned int dmem_emu_ap_count;
+static struct dmem_emu_ap_info dmem_emu_ap_list[DMEM_MAX_EMULATE_APS];
+
+/*
+ * This helper is used to determine the TAR increment size in bytes. The AP's
+ * CSW encoding for SIZE supports byte count decode using "1 << SIZE".
+ */
+static uint32_t dmem_memap_tar_inc(uint32_t csw)
+{
+ if ((csw & CSW_ADDRINC_MASK) != 0)
+ return 1 << (csw & CSW_SIZE_MASK);
+ return 0;
+}
+
+/*
+ * EMULATION MODE: In Emulation MODE, we assume the following:
+ * TCL still describes as system is operational from the view of AP (ex. jtag)
+ * However, the hardware doesn't permit direct memory access to these APs
+ * (only permitted via JTAG).
+ *
+ * So, the access to these APs have to be decoded to a memory map
+ * access which we can directly access.
+ *
+ * A few TI processors have this issue.
+ */
+static bool dmem_is_emulated_ap(struct adiv5_ap *ap, unsigned int *idx)
+{
+ for (unsigned int i = 0; i < dmem_emu_ap_count; i++) {
+ if (ap->ap_num == dmem_emu_ap_list[i].ap_num) {
+ *idx = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+static void dmem_emu_set_ap_reg(uint64_t addr, uint32_t val)
+{
+ addr &= ~ARM_APB_PADDR31;
+
+ *(volatile uint32_t *)((uintptr_t)dmem_emu_virt_base_addr + addr) = val;
+}
+
+static uint32_t dmem_emu_get_ap_reg(uint64_t addr)
+{
+ uint32_t val;
+
+ addr &= ~ARM_APB_PADDR31;
+
+ val = *(volatile uint32_t *)((uintptr_t)dmem_emu_virt_base_addr + addr);
+
+ return val;
+}
+
+static int dmem_emu_ap_q_read(unsigned int ap_idx, unsigned int reg, uint32_t *data)
+{
+ uint64_t addr;
+ int ret = ERROR_OK;
+ struct dmem_emu_ap_info *ap_info = &dmem_emu_ap_list[ap_idx];
+
+ switch (reg) {
+ case ADIV5_MEM_AP_REG_CSW:
+ *data = ap_info->apbap_csw;
+ break;
+ case ADIV5_MEM_AP_REG_TAR:
+ *data = ap_info->apbap_tar;
+ break;
+ case ADIV5_MEM_AP_REG_CFG:
+ *data = 0;
+ break;
+ case ADIV5_MEM_AP_REG_BASE:
+ *data = 0;
+ break;
+ case ADIV5_AP_REG_IDR:
+ *data = 0;
+ break;
+ case ADIV5_MEM_AP_REG_BD0:
+ case ADIV5_MEM_AP_REG_BD1:
+ case ADIV5_MEM_AP_REG_BD2:
+ case ADIV5_MEM_AP_REG_BD3:
+ addr = (ap_info->apbap_tar & ~0xf) + (reg & 0x0C);
+
+ *data = dmem_emu_get_ap_reg(addr);
+
+ break;
+ case ADIV5_MEM_AP_REG_DRW:
+ addr = ap_info->apbap_tar;
+
+ *data = dmem_emu_get_ap_reg(addr);
+
+ ap_info->apbap_tar += dmem_memap_tar_inc(ap_info->apbap_csw);
+ break;
+ default:
+ LOG_INFO("%s: Unknown reg: 0x%02x", __func__, reg);
+ ret = ERROR_FAIL;
+ break;
+ }
+
+ /* Track the last error code. */
+ if (ret != ERROR_OK)
+ dmem_dap_retval = ret;
+
+ return ret;
+}
+
+static int dmem_emu_ap_q_write(unsigned int ap_idx, unsigned int reg, uint32_t data)
+{
+ uint64_t addr;
+ int ret = ERROR_OK;
+ struct dmem_emu_ap_info *ap_info = &dmem_emu_ap_list[ap_idx];
+
+ switch (reg) {
+ case ADIV5_MEM_AP_REG_CSW:
+ /*
+ * This implementation only supports 32-bit accesses.
+ * Force this by ensuring CSW_SIZE field indicates 32-BIT.
+ */
+ ap_info->apbap_csw = ((data & ~CSW_SIZE_MASK) | CSW_32BIT);
+ break;
+ case ADIV5_MEM_AP_REG_TAR:
+ /*
+ * This implementation only supports 32-bit accesses.
+ * Force LS 2-bits of TAR to 00b
+ */
+ ap_info->apbap_tar = (data & ~0x3);
+ break;
+
+ case ADIV5_MEM_AP_REG_CFG:
+ case ADIV5_MEM_AP_REG_BASE:
+ case ADIV5_AP_REG_IDR:
+ /* We don't use this, so we don't need to store */
+ break;
+
+ case ADIV5_MEM_AP_REG_BD0:
+ case ADIV5_MEM_AP_REG_BD1:
+ case ADIV5_MEM_AP_REG_BD2:
+ case ADIV5_MEM_AP_REG_BD3:
+ addr = (ap_info->apbap_tar & ~0xf) + (reg & 0x0C);
+
+ dmem_emu_set_ap_reg(addr, data);
+
+ break;
+ case ADIV5_MEM_AP_REG_DRW:
+ addr = ap_info->apbap_tar;
+ dmem_emu_set_ap_reg(addr, data);
+
+ ap_info->apbap_tar += dmem_memap_tar_inc(ap_info->apbap_csw);
+ break;
+ default:
+ LOG_INFO("%s: Unknown reg: 0x%02x", __func__, reg);
+ ret = EINVAL;
+ break;
+ }
+
+ /* Track the last error code. */
+ if (ret != ERROR_OK)
+ dmem_dap_retval = ret;
+
+ return ret;
+}
+
+/* AP MODE */
+static uint32_t dmem_get_ap_reg_offset(struct adiv5_ap *ap, unsigned int reg)
+{
+ return (dmem_dap_ap_offset * ap->ap_num) + reg;
+}
+
+static void dmem_set_ap_reg(struct adiv5_ap *ap, unsigned int reg, uint32_t val)
+{
+ *(volatile uint32_t *)((uintptr_t)dmem_virt_base_addr +
+ dmem_get_ap_reg_offset(ap, reg)) = val;
+}
+
+static uint32_t dmem_get_ap_reg(struct adiv5_ap *ap, unsigned int reg)
+{
+ return *(volatile uint32_t *)((uintptr_t)dmem_virt_base_addr +
+ dmem_get_ap_reg_offset(ap, reg));
+}
+
+static int dmem_dp_q_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
+{
+ if (!data)
+ return ERROR_OK;
+
+ switch (reg) {
+ case DP_CTRL_STAT:
+ *data = CDBGPWRUPACK | CSYSPWRUPACK;
+ break;
+
+ default:
+ *data = 0;
+ break;
+ }
+
+ return ERROR_OK;
+}
+
+static int dmem_dp_q_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
+{
+ return ERROR_OK;
+}
+
+static int dmem_ap_q_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
+{
+ unsigned int idx;
+
+ if (is_adiv6(ap->dap)) {
+ static bool error_flagged;
+
+ if (!error_flagged)
+ LOG_ERROR("ADIv6 dap not supported by dmem dap-direct mode");
+
+ error_flagged = true;
+
+ return ERROR_FAIL;
+ }
+
+ if (dmem_is_emulated_ap(ap, &idx))
+ return dmem_emu_ap_q_read(idx, reg, data);
+
+ *data = dmem_get_ap_reg(ap, reg);
+
+ return ERROR_OK;
+}
+
+static int dmem_ap_q_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
+{
+ unsigned int idx;
+
+ if (is_adiv6(ap->dap)) {
+ static bool error_flagged;
+
+ if (!error_flagged)
+ LOG_ERROR("ADIv6 dap not supported by dmem dap-direct mode");
+
+ error_flagged = true;
+
+ return ERROR_FAIL;
+ }
+
+ if (dmem_is_emulated_ap(ap, &idx))
+ return dmem_emu_ap_q_write(idx, reg, data);
+
+ dmem_set_ap_reg(ap, reg, data);
+
+ return ERROR_OK;
+}
+
+static int dmem_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
+{
+ return ERROR_OK;
+}
+
+static int dmem_dp_run(struct adiv5_dap *dap)
+{
+ int retval = dmem_dap_retval;
+
+ /* Clear the error code. */
+ dmem_dap_retval = ERROR_OK;
+
+ return retval;
+}
+
+static int dmem_connect(struct adiv5_dap *dap)
+{
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_dap_device_command)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ free(dmem_dev_path);
+ dmem_dev_path = strdup(CMD_ARGV[0]);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_dap_base_address_command)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], dmem_dap_base_address);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_dap_max_aps_command)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], dmem_dap_max_aps);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_dap_ap_offset_command)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], dmem_dap_ap_offset);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_emu_base_address_command)
+{
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], dmem_emu_base_address);
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], dmem_emu_size);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_emu_ap_list_command)
+{
+ uint64_t em_ap;
+
+ if (CMD_ARGC < 1 || CMD_ARGC > DMEM_MAX_EMULATE_APS)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ for (unsigned int i = 0; i < CMD_ARGC; i++) {
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[i], em_ap);
+ dmem_emu_ap_list[i].ap_num = em_ap;
+ }
+
+ dmem_emu_ap_count = CMD_ARGC;
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(dmem_dap_config_info_command)
+{
+ if (CMD_ARGC != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ command_print(CMD, "dmem (Direct Memory) AP Adapter Configuration:");
+ command_print(CMD, " Device : %s",
+ dmem_dev_path ? dmem_dev_path : DMEM_DEV_PATH_DEFAULT);
+ command_print(CMD, " Base Address : 0x%" PRIx64, dmem_dap_base_address);
+ command_print(CMD, " Max APs : %u", dmem_dap_max_aps);
+ command_print(CMD, " AP offset : 0x%08" PRIx32, dmem_dap_ap_offset);
+ command_print(CMD, " Emulated AP Count : %u", dmem_emu_ap_count);
+
+ if (dmem_emu_ap_count) {
+ command_print(CMD, " Emulated AP details:");
+ command_print(CMD, " Emulated address : 0x%" PRIx64, dmem_emu_base_address);
+ command_print(CMD, " Emulated size : 0x%" PRIx64, dmem_emu_size);
+ for (unsigned int i = 0; i < dmem_emu_ap_count; i++)
+ command_print(CMD, " Emulated AP [%u] : %" PRIx64, i,
+ dmem_emu_ap_list[i].ap_num);
+ }
+ return ERROR_OK;
+}
+
+static const struct command_registration dmem_dap_subcommand_handlers[] = {
+ {
+ .name = "info",
+ .handler = dmem_dap_config_info_command,
+ .mode = COMMAND_ANY,
+ .help = "print the config info",
+ .usage = "",
+ },
+ {
+ .name = "device",
+ .handler = dmem_dap_device_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the dmem memory access device (default: /dev/mem)",
+ .usage = "device_path",
+ },
+ {
+ .name = "base_address",
+ .handler = dmem_dap_base_address_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the dmem dap AP memory map base address",
+ .usage = "base_address",
+ },
+ {
+ .name = "ap_address_offset",
+ .handler = dmem_dap_ap_offset_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the offsets of each ap index",
+ .usage = "offset_address",
+ },
+ {
+ .name = "max_aps",
+ .handler = dmem_dap_max_aps_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the maximum number of APs this will support",
+ .usage = "n",
+ },
+ {
+ .name = "emu_ap_list",
+ .handler = dmem_emu_ap_list_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the list of AP indices to be emulated (upto max)",
+ .usage = "n",
+ },
+ {
+ .name = "emu_base_address_range",
+ .handler = dmem_emu_base_address_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the base address and size of emulated AP range (all emulated APs access this range)",
+ .usage = "base_address address_window_size",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration dmem_dap_command_handlers[] = {
+ {
+ .name = "dmem",
+ .mode = COMMAND_ANY,
+ .help = "Perform dmem (Direct Memory) DAP management and configuration",
+ .chain = dmem_dap_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static int dmem_dap_init(void)
+{
+ char *path = dmem_dev_path ? dmem_dev_path : DMEM_DEV_PATH_DEFAULT;
+ uint32_t dmem_total_memory_window_size;
+ long page_size = sysconf(_SC_PAGESIZE);
+ size_t dmem_mapped_start, dmem_mapped_end;
+ long start_delta;
+ int dmem_fd;
+
+ if (!dmem_dap_base_address) {
+ LOG_ERROR("dmem DAP Base address NOT set? value is 0");
+ return ERROR_FAIL;
+ }
+
+ dmem_fd = open(path, O_RDWR | O_SYNC);
+ if (dmem_fd == -1) {
+ LOG_ERROR("Unable to open %s", path);
+ return ERROR_FAIL;
+ }
+
+ dmem_total_memory_window_size = (dmem_dap_max_aps + 1) * dmem_dap_ap_offset;
+
+ dmem_mapped_start = dmem_dap_base_address;
+ dmem_mapped_end = dmem_dap_base_address + dmem_total_memory_window_size;
+ /* mmap() requires page aligned offsets */
+ dmem_mapped_start = ALIGN_DOWN(dmem_mapped_start, page_size);
+ dmem_mapped_end = ALIGN_UP(dmem_mapped_end, page_size);
+
+ dmem_mapped_size = dmem_mapped_end - dmem_mapped_start;
+ start_delta = dmem_mapped_start - dmem_dap_base_address;
+
+ dmem_map_base = mmap(NULL,
+ dmem_mapped_size,
+ (PROT_READ | PROT_WRITE),
+ MAP_SHARED, dmem_fd,
+ dmem_mapped_start);
+ if (dmem_map_base == MAP_FAILED) {
+ LOG_ERROR("Mapping address 0x%lx for 0x%lx bytes failed!",
+ dmem_mapped_start, dmem_mapped_size);
+ goto error_fail;
+ }
+
+ dmem_virt_base_addr = (void *)((uintptr_t)dmem_map_base + start_delta);
+
+ /* Lets Map the emulated address if necessary */
+ if (dmem_emu_ap_count) {
+ dmem_mapped_start = dmem_emu_base_address;
+ dmem_mapped_end = dmem_emu_base_address + dmem_emu_size;
+ /* mmap() requires page aligned offsets */
+ dmem_mapped_start = ALIGN_DOWN(dmem_mapped_start, page_size);
+ dmem_mapped_end = ALIGN_UP(dmem_mapped_end, page_size);
+
+ dmem_emu_mapped_size = dmem_mapped_end - dmem_mapped_start;
+ start_delta = dmem_mapped_start - dmem_emu_base_address;
+
+ dmem_emu_map_base = mmap(NULL,
+ dmem_emu_mapped_size,
+ (PROT_READ | PROT_WRITE),
+ MAP_SHARED, dmem_fd,
+ dmem_mapped_start);
+ if (dmem_emu_map_base == MAP_FAILED) {
+ LOG_ERROR("Mapping EMU address 0x%lx for 0x%lx bytes failed!",
+ dmem_emu_base_address, dmem_emu_size);
+ goto error_fail;
+ }
+ dmem_emu_virt_base_addr = (void *)((uintptr_t)dmem_emu_map_base +
+ start_delta);
+ }
+
+ close(dmem_fd);
+ return ERROR_OK;
+
+error_fail:
+ close(dmem_fd);
+ return ERROR_FAIL;
+}
+
+static int dmem_dap_quit(void)
+{
+ if (munmap(dmem_map_base, dmem_mapped_size) == -1)
+ LOG_ERROR("%s: Failed to unmap mapped memory!", __func__);
+
+ if (dmem_emu_ap_count
+ && munmap(dmem_emu_map_base, dmem_emu_mapped_size) == -1)
+ LOG_ERROR("%s: Failed to unmap emu mapped memory!", __func__);
+
+ return ERROR_OK;
+}
+
+static int dmem_dap_reset(int req_trst, int req_srst)
+{
+ return ERROR_OK;
+}
+
+static int dmem_dap_speed(int speed)
+{
+ return ERROR_OK;
+}
+
+static int dmem_dap_khz(int khz, int *jtag_speed)
+{
+ *jtag_speed = khz;
+ return ERROR_OK;
+}
+
+static int dmem_dap_speed_div(int speed, int *khz)
+{
+ *khz = speed;
+ return ERROR_OK;
+}
+
+/* DAP operations. */
+static const struct dap_ops dmem_dap_ops = {
+ .connect = dmem_connect,
+ .queue_dp_read = dmem_dp_q_read,
+ .queue_dp_write = dmem_dp_q_write,
+ .queue_ap_read = dmem_ap_q_read,
+ .queue_ap_write = dmem_ap_q_write,
+ .queue_ap_abort = dmem_ap_q_abort,
+ .run = dmem_dp_run,
+};
+
+static const char *const dmem_dap_transport[] = { "dapdirect_swd", NULL };
+
+struct adapter_driver dmem_dap_adapter_driver = {
+ .name = "dmem",
+ .transports = dmem_dap_transport,
+ .commands = dmem_dap_command_handlers,
+
+ .init = dmem_dap_init,
+ .quit = dmem_dap_quit,
+ .reset = dmem_dap_reset,
+ .speed = dmem_dap_speed,
+ .khz = dmem_dap_khz,
+ .speed_div = dmem_dap_speed_div,
+
+ .dap_swd_ops = &dmem_dap_ops,
+};
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index 2c5b63d..c5326a2 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -456,7 +456,7 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i
#define STLINK_DEBUG_PORT_ACCESS 0xffff
#define STLINK_TRACE_SIZE 4096
-#define STLINK_TRACE_MAX_HZ 2000000
+#define STLINK_TRACE_MAX_HZ 2250000
#define STLINK_V3_TRACE_MAX_HZ 24000000
#define STLINK_V3_MAX_FREQ_NB 10
diff --git a/src/jtag/interface.h b/src/jtag/interface.h
index 25ae7e8..3df4240 100644
--- a/src/jtag/interface.h
+++ b/src/jtag/interface.h
@@ -370,6 +370,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 cmsis_dap_adapter_driver;
+extern struct adapter_driver dmem_dap_adapter_driver;
extern struct adapter_driver dummy_adapter_driver;
extern struct adapter_driver ep93xx_adapter_driver;
extern struct adapter_driver esp_usb_adapter_driver;
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index aa0ad3a..c24ead8 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -147,6 +147,9 @@ struct adapter_driver *adapter_drivers[] = {
#if BUILD_RSHIM == 1
&rshim_dap_adapter_driver,
#endif
+#if BUILD_DMEM == 1
+ &dmem_dap_adapter_driver,
+#endif
#if BUILD_AM335XGPIO == 1
&am335xgpio_adapter_driver,
#endif
diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c
index 934a8dd..a4c6090 100644
--- a/src/rtos/zephyr.c
+++ b/src/rtos/zephyr.c
@@ -57,6 +57,7 @@ enum zephyr_offsets {
OFFSET_T_ARCH,
OFFSET_T_PREEMPT_FLOAT,
OFFSET_T_COOP_FLOAT,
+ OFFSET_T_ARM_EXC_RETURN,
OFFSET_MAX
};
diff --git a/src/target/Makefile.am b/src/target/Makefile.am
index 2084de6..1fc7d2a 100644
--- a/src/target/Makefile.am
+++ b/src/target/Makefile.am
@@ -204,6 +204,7 @@ ARC_SRC = \
%D%/image.h \
%D%/mips32.h \
%D%/mips64.h \
+ %D%/mips_cpu.h \
%D%/mips_m4k.h \
%D%/mips_mips64.h \
%D%/mips_ejtag.h \
diff --git a/src/target/arm.h b/src/target/arm.h
index f3abd6c..28e5330 100644
--- a/src/target/arm.h
+++ b/src/target/arm.h
@@ -61,6 +61,7 @@ enum arm_arch {
/** Known ARM implementor IDs */
enum arm_implementor {
ARM_IMPLEMENTOR_ARM = 0x41,
+ ARM_IMPLEMENTOR_REALTEK = 0x72,
};
/**
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 87a8845..014ceae 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -111,6 +111,17 @@ static const struct cortex_m_part_info cortex_m_parts[] = {
.arch = ARM_ARCH_V8M,
.flags = CORTEX_M_F_HAS_FPV5,
},
+ {
+ .impl_part = REALTEK_M200_PARTNO,
+ .name = "Real-M200 (KM0)",
+ .arch = ARM_ARCH_V8M,
+ },
+ {
+ .impl_part = REALTEK_M300_PARTNO,
+ .name = "Real-M300 (KM4)",
+ .arch = ARM_ARCH_V8M,
+ .flags = CORTEX_M_F_HAS_FPV5,
+ },
};
/* forward declarations */
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index 806ff59..b5d1da7 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -56,6 +56,8 @@ enum cortex_m_impl_part {
CORTEX_M33_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD21),
CORTEX_M35P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD31),
CORTEX_M55_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD22),
+ REALTEK_M200_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd20),
+ REALTEK_M300_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd22),
};
/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */
diff --git a/src/target/mips32.c b/src/target/mips32.c
index ce16a7b..4e6d251 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -18,6 +18,7 @@
#endif
#include "mips32.h"
+#include "mips_cpu.h"
#include "breakpoints.h"
#include "algorithm.h"
#include "register.h"
@@ -693,6 +694,63 @@ int mips32_enable_interrupts(struct target *target, int enable)
return ERROR_OK;
}
+/* read processor identification cp0 register */
+static int mips32_read_c0_prid(struct target *target)
+{
+ struct mips32_common *mips32 = target_to_mips32(target);
+ struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+ int retval;
+
+ retval = mips32_cp0_read(ejtag_info, &mips32->prid, 15, 0);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("processor id not available, failed to read cp0 PRId register");
+ mips32->prid = 0;
+ }
+
+ return retval;
+}
+
+/*
+ * Detect processor type and apply required quirks.
+ *
+ * NOTE: The proper detection of certain CPUs can become quite complicated.
+ * Please consult the following Linux kernel code when adding new CPUs:
+ * arch/mips/include/asm/cpu.h
+ * arch/mips/kernel/cpu-probe.c
+ */
+int mips32_cpu_probe(struct target *target)
+{
+ struct mips32_common *mips32 = target_to_mips32(target);
+ const char *cpu_name = "unknown";
+ int retval;
+
+ if (mips32->prid)
+ return ERROR_OK; /* Already probed once, return early. */
+
+ retval = mips32_read_c0_prid(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ switch (mips32->prid & PRID_COMP_MASK) {
+ case PRID_COMP_INGENIC_E1:
+ switch (mips32->prid & PRID_IMP_MASK) {
+ case PRID_IMP_XBURST_REV1:
+ cpu_name = "Ingenic XBurst rev1";
+ mips32->cpu_quirks |= EJTAG_QUIRK_PAD_DRET;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ LOG_DEBUG("CPU: %s (PRId %08x)", cpu_name, mips32->prid);
+
+ return ERROR_OK;
+}
+
/* read config to config3 cp0 registers and log isa implementation */
int mips32_read_config_regs(struct target *target)
{
diff --git a/src/target/mips32.h b/src/target/mips32.h
index 81b6d64..3d03e98 100644
--- a/src/target/mips32.h
+++ b/src/target/mips32.h
@@ -13,6 +13,8 @@
#ifndef OPENOCD_TARGET_MIPS32_H
#define OPENOCD_TARGET_MIPS32_H
+#include <helper/bits.h>
+
#include "target.h"
#include "mips32_pracc.h"
@@ -55,6 +57,9 @@
#define MIPS32_SCAN_DELAY_LEGACY_MODE 2000000
+/* Insert extra NOPs after the DRET instruction on exit from debug. */
+#define EJTAG_QUIRK_PAD_DRET BIT(0)
+
/* offsets into mips32 core register cache */
enum {
MIPS32_PC = 37,
@@ -91,6 +96,11 @@ struct mips32_common {
enum mips32_isa_mode isa_mode;
enum mips32_isa_imp isa_imp;
+ /* processor identification register */
+ uint32_t prid;
+ /* CPU specific quirks */
+ uint32_t cpu_quirks;
+
/* working area for fastdata access */
struct working_area *fast_data_area;
@@ -408,6 +418,8 @@ int mips32_enable_interrupts(struct target *target, int enable);
int mips32_examine(struct target *target);
+int mips32_cpu_probe(struct target *target);
+
int mips32_read_config_regs(struct target *target);
int mips32_register_commands(struct command_context *cmd_ctx);
diff --git a/src/target/mips_cpu.h b/src/target/mips_cpu.h
new file mode 100644
index 0000000..8190b32
--- /dev/null
+++ b/src/target/mips_cpu.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef OPENOCD_TARGET_MIPS_CPU_H
+#define OPENOCD_TARGET_MIPS_CPU_H
+
+/*
+ * NOTE: The proper detection of certain CPUs can become quite complicated.
+ * Please consult the following Linux kernel code when adding new CPUs:
+ * arch/mips/include/asm/cpu.h
+ * arch/mips/kernel/cpu-probe.c
+ */
+
+/* Assigned Company values for bits 23:16 of the PRId register. */
+#define PRID_COMP_MASK 0xff0000
+
+#define PRID_COMP_LEGACY 0x000000
+#define PRID_COMP_INGENIC_E1 0xe10000
+
+/*
+ * Assigned Processor ID (implementation) values for bits 15:8 of the PRId
+ * register. In order to detect a certain CPU type exactly eventually additional
+ * registers may need to be examined.
+ */
+#define PRID_IMP_MASK 0xff00
+
+#define PRID_IMP_XBURST_REV1 0x0200 /* XBurst®1 with MXU1.0/MXU1.1 SIMD ISA */
+
+#endif /* OPENOCD_TARGET_MIPS_CPU_H */
diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index a1a1792..5c92bf9 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -259,9 +259,12 @@ int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
{
struct pa_list pracc_list = {.instr = MIPS32_DRET(ejtag_info->isa), .addr = 0};
struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
+ struct mips32_common *mips32 = container_of(ejtag_info,
+ struct mips32_common, ejtag_info);
/* execute our dret instruction */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0); /* shift out instr, omit last check */
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL,
+ mips32->cpu_quirks & EJTAG_QUIRK_PAD_DRET);
/* pic32mx workaround, false pending at low core clock */
jtag_add_sleep(1000);
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 14e3f3b..46d241c 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -100,6 +100,8 @@ static int mips_m4k_debug_entry(struct target *target)
/* attempt to find halt reason */
mips_m4k_examine_debug_reason(target);
+ mips32_cpu_probe(target);
+
mips32_read_config_regs(target);
/* default to mips32 isa, it will be changed below if required */
diff --git a/tcl/board/ti_am625_swd_native.cfg b/tcl/board/ti_am625_swd_native.cfg
new file mode 100644
index 0000000..dc4b205
--- /dev/null
+++ b/tcl/board/ti_am625_swd_native.cfg
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2022-2023 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments am625
+# Link: https://www.ti.com/product/AM625
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every AM625 platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside AM625 and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+
+if { ![info exists SOC] } {
+ set SOC am625
+}
+
+source [find target/ti_k3.cfg]
diff --git a/tcl/board/ti_am62a7evm.cfg b/tcl/board/ti_am62a7evm.cfg
new file mode 100644
index 0000000..e407909
--- /dev/null
+++ b/tcl/board/ti_am62a7evm.cfg
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments am62a7 EVM/SK
+# Link: https://www.ti.com/tool/SK-AM62A-LP
+#
+
+# AM62a7 EVM/SK has an xds110 onboard.
+source [find interface/xds110.cfg]
+
+transport select jtag
+
+# default JTAG configuration has only SRST and no TRST
+reset_config srst_only srst_push_pull
+
+# delay after SRST goes inactive
+adapter srst delay 20
+
+if { ![info exists SOC] } {
+ set SOC am62a7
+}
+
+source [find target/ti_k3.cfg]
+
+adapter speed 2500
diff --git a/tcl/board/ti_j721e_swd_native.cfg b/tcl/board/ti_j721e_swd_native.cfg
new file mode 100644
index 0000000..3041c3c
--- /dev/null
+++ b/tcl/board/ti_j721e_swd_native.cfg
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2022-2023 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments TDA4VM/J721E
+# Link: https://www.ti.com/product/TDA4VM
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every TDA4VM platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside TDA4VM and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+
+if { ![info exists SOC] } {
+ set SOC j721e
+}
+source [find target/ti_k3.cfg]
diff --git a/tcl/cpu/arc/v2.tcl b/tcl/cpu/arc/v2.tcl
index d28b9d9..b24a67d 100644
--- a/tcl/cpu/arc/v2.tcl
+++ b/tcl/cpu/arc/v2.tcl
@@ -173,8 +173,8 @@ proc arc_v2_init_regs { } {
r19 19 uint32
r20 20 uint32
r21 21 uint32
- r22 23 uint32
- r23 24 uint32
+ r22 22 uint32
+ r23 23 uint32
r24 24 uint32
r25 25 uint32
gp 26 data_ptr
diff --git a/tcl/target/rtl872xd.cfg b/tcl/target/rtl872xd.cfg
new file mode 100644
index 0000000..65730e2
--- /dev/null
+++ b/tcl/target/rtl872xd.cfg
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+# Realtek RTL872xD (ARM Cortex-M33 + M23, wifi+bt dualband soc)
+
+# HLA does not support AP other than 0
+if { [using_hla] } {
+ echo "ERROR: HLA transport cannot work with this target."
+ shutdown
+}
+
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME rtl872xd
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x6ba02477
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME.km0 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1
+target create $_TARGETNAME.km4 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 2
+
+cortex_m reset_config sysresetreq
+
+adapter speed 1000
diff --git a/tcl/target/ti_k3.cfg b/tcl/target/ti_k3.cfg
index 2454357..f0881cd 100644
--- a/tcl/target/ti_k3.cfg
+++ b/tcl/target/ti_k3.cfg
@@ -8,8 +8,14 @@
# Has 2 ARMV8 Cores and 6 R5 Cores and an M3
# * J7200: https://www.ti.com/lit/pdf/spruiu1
# Has 2 ARMV8 Cores and 4 R5 Cores and an M3
+# * J721S2: https://www.ti.com/lit/pdf/spruj28
+# Has 2 ARMV8 Cores and 6 R5 Cores and an M4F
# * AM642: https://www.ti.com/lit/pdf/spruim2
# Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3
+# * AM625: https://www.ti.com/lit/pdf/spruiv7a
+# Has 4 ARMV8 Cores and 1 R5 Core and an M4F
+# * AM62a7: https://www.ti.com/lit/pdf/spruj16a
+# Has 4 ARMV8 Cores and 2 R5 Cores
#
source [find target/swj-dp.tcl]
@@ -114,6 +120,37 @@ switch $_soc {
# M4 processor
set _gp_mcu_cores 1
set _gp_mcu_ap_unlock_offsets {0xf0 0x7c}
+
+ # Setup DMEM access descriptions
+ # DAPBUS (Debugger) description
+ set _dmem_base_address 0x740002000
+ set _dmem_ap_address_offset 0x100
+ set _dmem_max_aps 10
+ # Emulated AP description
+ set _dmem_emu_base_address 0x760000000
+ set _dmem_emu_base_address_map_to 0x1d500000
+ set _dmem_emu_ap_list 1
+ }
+ am62a7 {
+ set _CHIPNAME am62a7
+ set _K3_DAP_TAPID 0x0bb8d02f
+
+ # AM62a7 has 1 clusters of 4 A53 cores.
+ set _armv8_cpu_name a53
+ set _armv8_cores 4
+ set ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}
+ set ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}
+
+ # AM62a7 has 2 cluster of 1 R5s core.
+ set _r5_cores 2
+ set R5_NAMES {main0_r5.0 mcu0_r5.0}
+ set R5_DBGBASE {0x9d410000 0x9d810000}
+ set R5_CTIBASE {0x9d418000 0x9d818000}
+
+ # sysctrl CTI base
+ set CM3_CTIBASE {0x20001000}
+ # Sysctrl power-ap unlock offsets
+ set _sysctrl_ap_unlock_offsets {0xf0 0x78}
}
j721e {
set _CHIPNAME j721e
@@ -124,6 +161,16 @@ switch $_soc {
# J721E has 3 clusters of 2 R5 cores each.
set _r5_cores 6
+
+ # Setup DMEM access descriptions
+ # DAPBUS (Debugger) description
+ set _dmem_base_address 0x4c40002000
+ set _dmem_ap_address_offset 0x100
+ set _dmem_max_aps 8
+ # Emulated AP description
+ set _dmem_emu_base_address 0x4c60000000
+ set _dmem_emu_base_address_map_to 0x1d600000
+ set _dmem_emu_ap_list 1
}
j7200 {
set _CHIPNAME j7200
@@ -302,3 +349,22 @@ if { $_gp_mcu_cores != 0 } {
halt 1000
}
}
+
+# In case of DMEM access, configure the dmem adapter with offsets from above.
+if { 0 == [string compare [adapter name] dmem ] } {
+ if { [info exists _dmem_base_address] } {
+ # DAPBUS (Debugger) description
+ dmem base_address $_dmem_base_address
+ dmem ap_address_offset $_dmem_ap_address_offset
+ dmem max_aps $_dmem_max_aps
+
+ # The following are the details of APs to be emulated for direct address access.
+ # Debug Config (Debugger) description
+ dmem emu_base_address_range $_dmem_emu_base_address $_dmem_emu_base_address_map_to
+ dmem emu_ap_list $_dmem_emu_ap_list
+ # We are going local bus, so speed is really dummy here.
+ adapter speed 2500
+ } else {
+ puts "ERROR: ${SOC} data is missing to support dmem access!"
+ }
+}