Merge commit '18281b0c497694d91c5608be54583172838be75c' into from_upstream
Change-Id: I05cd5ef9b04fa61a27321ae9b6a4fecabe3dee80
This commit is contained in:
commit
92213132a6
15
configure.ac
15
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"])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 $@ $<
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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' ;
|
|
@ -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';
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -61,6 +61,7 @@ enum arm_arch {
|
|||
/** Known ARM implementor IDs */
|
||||
enum arm_implementor {
|
||||
ARM_IMPLEMENTOR_ARM = 0x41,
|
||||
ARM_IMPLEMENTOR_REALTEK = 0x72,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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!"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue