Merge commit '18281b0c497694d91c5608be54583172838be75c' into from_upstream

Change-Id: I05cd5ef9b04fa61a27321ae9b6a4fecabe3dee80
This commit is contained in:
Tim Newsome 2023-11-20 12:30:19 -08:00
commit 92213132a6
40 changed files with 1552 additions and 148 deletions

View File

@ -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"])

View File

@ -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

View File

@ -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 $@ $<

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
/**

View File

@ -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;
}

View File

@ -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

View File

@ -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' ;

View File

@ -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';

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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();
}

622
src/jtag/drivers/dmem.c Normal file
View File

@ -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,
};

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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
};

View File

@ -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 \

View File

@ -61,6 +61,7 @@ enum arm_arch {
/** Known ARM implementor IDs */
enum arm_implementor {
ARM_IMPLEMENTOR_ARM = 0x41,
ARM_IMPLEMENTOR_REALTEK = 0x72,
};
/**

View File

@ -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 */

View File

@ -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 */

View File

@ -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)
{

View File

@ -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);

27
src/target/mips_cpu.h Normal file
View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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]

View File

@ -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

View File

@ -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]

View File

@ -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

33
tcl/target/rtl872xd.cfg Normal file
View File

@ -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

View File

@ -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!"
}
}