forked from auracaster/openocd
Compare commits
23 Commits
v0.8.0-rc1
...
v0.8.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca218832bb | ||
|
|
cf094f22ca | ||
|
|
7bd295953d | ||
|
|
7ad635bb68 | ||
|
|
6812993483 | ||
|
|
186c442f9b | ||
|
|
11a1080c00 | ||
|
|
3427cf2b7e | ||
|
|
31496c2bed | ||
|
|
151c31785a | ||
|
|
cb11564219 | ||
|
|
3a590658e9 | ||
|
|
4835a21dea | ||
|
|
47830f0ebf | ||
|
|
e2b35204b3 | ||
|
|
b182f934f1 | ||
|
|
7256d6acdf | ||
|
|
ee54f7e9f0 | ||
|
|
85c1790beb | ||
|
|
45f71f1082 | ||
|
|
9f2bc3b830 | ||
|
|
61905a165f | ||
|
|
d7cbdee3e9 |
6
NEWS
6
NEWS
@@ -66,7 +66,7 @@ Board, Target, and Interface Configuration Scripts:
|
||||
* TI TMDX570LS31USB (TMS570, Cortex-R4) support scripts
|
||||
* Freescale FRDM-KL25Z, KL46Z board configs
|
||||
* Digilent Zedboard config
|
||||
* Asus RT-N16, Linksys WRT54GL board configs
|
||||
* Asus RT-N16, Linksys WRT54GL, BT HomeHub board configs
|
||||
* Atmel Xplained initial support
|
||||
* Broadcom bcm28155_ap board config
|
||||
* TUMPA, TUMPA Lite interface configs
|
||||
@@ -77,7 +77,7 @@ Board, Target, and Interface Configuration Scripts:
|
||||
|
||||
Server Layer:
|
||||
* Auto-generation of GDB target description for ARMv7-M,
|
||||
ARM4, nds23, OR1K, Quark
|
||||
ARM4, nds32, OR1K, Quark
|
||||
* GDB File-I/O Remote Protocol extension support
|
||||
* Default GDB flashing events handlers to initialise and reset
|
||||
the target automatically when "load" is used
|
||||
@@ -87,7 +87,7 @@ Documentation:
|
||||
* The official User's Guide was proofread
|
||||
* Example cross-build script
|
||||
* RTOS documentation improvements
|
||||
* Tcl RPC documentation added
|
||||
* Tcl RPC documentation and examples added
|
||||
|
||||
Build and Release:
|
||||
* *BSD, OS X, clang, ARM, windows build fixes
|
||||
|
||||
10
README.OSX
10
README.OSX
@@ -23,6 +23,12 @@ If you're using Homebrew, no custom flags are necessary.
|
||||
|
||||
See README for the generic building instructions.
|
||||
|
||||
If you use an FTDI-based adapter and have the FTDI kext installed, you
|
||||
will need to unload it prior to using OpenOCD:
|
||||
If you're using a USB adapter and have a driver kext matched to it,
|
||||
you will need to unload it prior to running OpenOCD. E.g. with Apple
|
||||
driver (OS X 10.9 or later) for FTDI run:
|
||||
sudo kextunload -b com.apple.driver.AppleUSBFTDI
|
||||
for FTDI vendor driver use:
|
||||
sudo kextunload FTDIUSBSerialDriver.kext
|
||||
|
||||
To learn more on the topic please refer to the official libusb FAQ:
|
||||
https://github.com/libusb/libusb/wiki/FAQ
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.64)
|
||||
AC_INIT([openocd], [0.8.0-rc1],
|
||||
AC_INIT([openocd], [0.8.0],
|
||||
[OpenOCD Mailing List <openocd-devel@lists.sourceforge.net>])
|
||||
AC_CONFIG_SRCDIR([src/openocd.c])
|
||||
|
||||
@@ -1014,7 +1014,7 @@ CFLAGS=$CFLAGS_SAVE
|
||||
fi
|
||||
|
||||
if test $build_ft2232_libftdi = yes -o $build_usb_blaster_libftdi = yes -o \
|
||||
$build_openjtag_ftdi = yes; then
|
||||
$build_openjtag_ftdi = yes -o $build_presto_libftdi = yes; then
|
||||
|
||||
# we can have libftdi or libftdi1, so check it and use the latest one
|
||||
PKG_CHECK_MODULES([LIBFTDI], [libftdi1], [use_libftdi=yes], [use_libftdi=no])
|
||||
|
||||
@@ -8,10 +8,6 @@ SUBSYSTEM!="usb|tty|hidraw", GOTO="openocd_rules_end"
|
||||
# opendous and estick
|
||||
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204f", MODE="664", GROUP="plugdev"
|
||||
|
||||
# Atmel EDBG CMSIS-DAP
|
||||
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE="664", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE="664", GROUP="plugdev"
|
||||
|
||||
# Original FT232/FT245 VID:PID
|
||||
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="664", GROUP="plugdev"
|
||||
|
||||
@@ -114,16 +110,7 @@ ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="664", GROUP="plugdev"
|
||||
# Marvell Sheevaplug
|
||||
ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="664", GROUP="plugdev"
|
||||
|
||||
# mbed CMSIS-DAP
|
||||
ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", MODE="664", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", MODE="664", GROUP="plugdev"
|
||||
|
||||
# Freescale Freedom Board CMSIS-DAP
|
||||
ATTRS{idVendor}=="c251", ATTRS{idProduct}=="f002", MODE="664", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="c251", ATTRS{idProduct}=="f002", MODE="664", GROUP="plugdev"
|
||||
|
||||
# Keil ULINK2 CMSIS-DAP
|
||||
ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2722", MODE="664", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2722", MODE="664", GROUP="plugdev"
|
||||
# CMSIS-DAP compatible adapters
|
||||
ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev"
|
||||
|
||||
LABEL="openocd_rules_end"
|
||||
|
||||
145
contrib/rpc_examples/ocd_rpc_example.py
Executable file
145
contrib/rpc_examples/ocd_rpc_example.py
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
OpenOCD RPC example, covered by GNU GPLv3 or later
|
||||
Copyright (C) 2014 Andreas Ortmann (ortmann@finf.uni-hannover.de)
|
||||
|
||||
|
||||
Example output:
|
||||
./ocd_rpc_example.py
|
||||
echo says hi!
|
||||
|
||||
target state: halted
|
||||
target halted due to debug-request, current mode: Thread
|
||||
xPSR: 0x01000000 pc: 0x00000188 msp: 0x10000fd8
|
||||
|
||||
variable @ 0x10000000: 0x01c9c380
|
||||
|
||||
variable @ 0x10000000: 0xdeadc0de
|
||||
|
||||
memory (before): ['0xdeadc0de', '0x00000011', '0xaaaaaaaa', '0x00000023',
|
||||
'0x00000042', '0x0000ffff']
|
||||
|
||||
memory (after): ['0x00000001', '0x00000000', '0xaaaaaaaa', '0x00000023',
|
||||
'0x00000042', '0x0000ffff']
|
||||
"""
|
||||
|
||||
import socket
|
||||
import itertools
|
||||
|
||||
def strToHex(data):
|
||||
return map(strToHex, data) if isinstance(data, list) else int(data, 16)
|
||||
|
||||
def hexify(data):
|
||||
return "<None>" if data is None else ("0x%08x" % data)
|
||||
|
||||
def compareData(a, b):
|
||||
for i, j, num in zip(a, b, itertools.count(0)):
|
||||
if i != j:
|
||||
print("difference at %d: %s != %s" % (num, hexify(i), hexify(j)))
|
||||
|
||||
|
||||
class OpenOcd:
|
||||
COMMAND_TOKEN = '\x1a'
|
||||
def __init__(self, verbose=False):
|
||||
self.verbose = verbose
|
||||
self.tclRpcIp = "127.0.0.1"
|
||||
self.tclRpcPort = 6666
|
||||
self.bufferSize = 4096
|
||||
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
def __enter__(self):
|
||||
self.sock.connect((self.tclRpcIp, self.tclRpcPort))
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
try:
|
||||
self.send("exit")
|
||||
finally:
|
||||
self.sock.close()
|
||||
|
||||
def send(self, cmd):
|
||||
"""Send a command string to TCL RPC. Return the result that was read."""
|
||||
data = (cmd + OpenOcd.COMMAND_TOKEN).encode("utf-8")
|
||||
if self.verbose:
|
||||
print("<- ", data)
|
||||
|
||||
self.sock.send(data)
|
||||
return self._recv()
|
||||
|
||||
def _recv(self):
|
||||
"""Read from the stream until the token (\x1a) was received."""
|
||||
data = bytes()
|
||||
while True:
|
||||
chunk = self.sock.recv(self.bufferSize)
|
||||
data += chunk
|
||||
if bytes(OpenOcd.COMMAND_TOKEN, encoding="utf-8") in chunk:
|
||||
break
|
||||
|
||||
if self.verbose:
|
||||
print("-> ", data)
|
||||
|
||||
data = data.decode("utf-8").strip()
|
||||
data = data[:-1] # strip trailing \x1a
|
||||
|
||||
return data
|
||||
|
||||
def readVariable(self, address):
|
||||
raw = self.send("ocd_mdw 0x%x" % address).split(": ")
|
||||
return None if (len(raw) < 2) else strToHex(raw[1])
|
||||
|
||||
def readMemory(self, wordLen, address, n):
|
||||
self.send("array unset output") # better to clear the array before
|
||||
self.send("mem2array output %d 0x%x %d" % (wordLen, address, n))
|
||||
|
||||
output = self.send("ocd_echo $output").split(" ")
|
||||
|
||||
return [int(output[2*i+1]) for i in range(len(output)//2)]
|
||||
|
||||
def writeVariable(self, address, value):
|
||||
assert value is not None
|
||||
self.send("mww 0x%x 0x%x" % (address, value))
|
||||
|
||||
def writeMemory(self, wordLen, address, n, data):
|
||||
array = " ".join(["%d 0x%x" % (a, b) for a, b in enumerate(data)])
|
||||
|
||||
self.send("array unset 1986ве1т") # better to clear the array before
|
||||
self.send("array set 1986ве1т { %s }" % array)
|
||||
self.send("array2mem 1986ве1т 0x%x %s %d" % (wordLen, address, n))
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
def show(*args):
|
||||
print(*args, end="\n\n")
|
||||
|
||||
with OpenOcd() as ocd:
|
||||
ocd.send("reset")
|
||||
|
||||
show(ocd.send("ocd_echo \"echo says hi!\"")[:-1])
|
||||
show(ocd.send("capture \"ocd_halt\"")[:-1])
|
||||
|
||||
# Read the first few words at the RAM region (put starting adress of RAM
|
||||
# region into 'addr')
|
||||
addr = 0x10000000
|
||||
|
||||
value = ocd.readVariable(addr)
|
||||
show("variable @ %s: %s" % (hexify(addr), hexify(value)))
|
||||
|
||||
ocd.writeVariable(addr, 0xdeadc0de)
|
||||
show("variable @ %s: %s" % (hexify(addr), hexify(ocd.readVariable(addr))))
|
||||
|
||||
data = [1, 0, 0xaaaaaaaa, 0x23, 0x42, 0xffff]
|
||||
wordlen = 32
|
||||
n = len(data)
|
||||
|
||||
read = ocd.readMemory(wordlen, addr, n)
|
||||
show("memory (before):", list(map(hexify, read)))
|
||||
|
||||
ocd.writeMemory(wordlen, addr, n, data)
|
||||
|
||||
read = ocd.readMemory(wordlen, addr, n)
|
||||
show("memory (after):", list(map(hexify, read)))
|
||||
|
||||
compareData(read, data)
|
||||
|
||||
ocd.send("resume")
|
||||
@@ -52,7 +52,7 @@ libopenocd_la_CPPFLAGS += -DGITVERSION=\"`cd $(top_srcdir) && git describe`\"
|
||||
endif
|
||||
|
||||
# add default CPPFLAGS
|
||||
libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS) $(LIBFTDI_CFLAGS)
|
||||
libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS)
|
||||
|
||||
# the library search path.
|
||||
libopenocd_la_LDFLAGS = $(all_libraries)
|
||||
|
||||
@@ -3335,93 +3335,6 @@ static int sam3_page_read(struct sam3_bank_private *pPrivate, unsigned pagenum,
|
||||
return r;
|
||||
}
|
||||
|
||||
/* The code below is basically this: */
|
||||
/* compiled with */
|
||||
/* arm-none-eabi-gcc -mthumb -mcpu = cortex-m3 -O9 -S ./foobar.c -o foobar.s */
|
||||
/* */
|
||||
/* Only the *CPU* can write to the flash buffer. */
|
||||
/* the DAP cannot... so - we download this 28byte thing */
|
||||
/* Run the algorithm - (below) */
|
||||
/* to program the device */
|
||||
/* */
|
||||
/* ======================================== */
|
||||
/* #include <stdint.h> */
|
||||
/* */
|
||||
/* struct foo { */
|
||||
/* uint32_t *dst; */
|
||||
/* const uint32_t *src; */
|
||||
/* int n; */
|
||||
/* volatile uint32_t *base; */
|
||||
/* uint32_t cmd; */
|
||||
/* }; */
|
||||
/* */
|
||||
/* */
|
||||
/* uint32_t sam3_function(struct foo *p) */
|
||||
/* { */
|
||||
/* volatile uint32_t *v; */
|
||||
/* uint32_t *d; */
|
||||
/* const uint32_t *s; */
|
||||
/* int n; */
|
||||
/* uint32_t r; */
|
||||
/* */
|
||||
/* d = p->dst; */
|
||||
/* s = p->src; */
|
||||
/* n = p->n; */
|
||||
/* */
|
||||
/* do { */
|
||||
/* *d++ = *s++; */
|
||||
/* } while (--n) */
|
||||
/* ; */
|
||||
/* */
|
||||
/* v = p->base; */
|
||||
/* */
|
||||
/* v[ 1 ] = p->cmd; */
|
||||
/* do { */
|
||||
/* r = v[8/4]; */
|
||||
/* } while (!(r&1)) */
|
||||
/* ; */
|
||||
/* return r; */
|
||||
/* } */
|
||||
/* ======================================== */
|
||||
|
||||
static const uint8_t
|
||||
sam3_page_write_opcodes[] = {
|
||||
/* 24 0000 0446 mov r4, r0 */
|
||||
0x04, 0x46,
|
||||
/* 25 0002 6168 ldr r1, [r4, #4] */
|
||||
0x61, 0x68,
|
||||
/* 26 0004 0068 ldr r0, [r0, #0] */
|
||||
0x00, 0x68,
|
||||
/* 27 0006 A268 ldr r2, [r4, #8] */
|
||||
0xa2, 0x68,
|
||||
/* 28 @ lr needed for prologue */
|
||||
/* 29 .L2: */
|
||||
/* 30 0008 51F8043B ldr r3, [r1], #4 */
|
||||
0x51, 0xf8, 0x04, 0x3b,
|
||||
/* 31 000c 12F1FF32 adds r2, r2, #-1 */
|
||||
0x12, 0xf1, 0xff, 0x32,
|
||||
/* 32 0010 40F8043B str r3, [r0], #4 */
|
||||
0x40, 0xf8, 0x04, 0x3b,
|
||||
/* 33 0014 F8D1 bne .L2 */
|
||||
0xf8, 0xd1,
|
||||
/* 34 0016 E268 ldr r2, [r4, #12] */
|
||||
0xe2, 0x68,
|
||||
/* 35 0018 2369 ldr r3, [r4, #16] */
|
||||
0x23, 0x69,
|
||||
/* 36 001a 5360 str r3, [r2, #4] */
|
||||
0x53, 0x60,
|
||||
/* 37 001c 0832 adds r2, r2, #8 */
|
||||
0x08, 0x32,
|
||||
/* 38 .L4: */
|
||||
/* 39 001e 1068 ldr r0, [r2, #0] */
|
||||
0x10, 0x68,
|
||||
/* 40 0020 10F0010F tst r0, #1 */
|
||||
0x10, 0xf0, 0x01, 0x0f,
|
||||
/* 41 0024 FBD0 beq .L4 */
|
||||
0xfb, 0xd0,
|
||||
0x00, 0xBE /* bkpt #0 */
|
||||
};
|
||||
|
||||
static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
|
||||
{
|
||||
uint32_t adr;
|
||||
|
||||
@@ -629,7 +629,7 @@ static int nrf51_write_page(struct flash_bank *bank, uint32_t offset, const uint
|
||||
struct flash_sector *sector = nrf51_find_sector_by_address(bank, offset);
|
||||
|
||||
if (!sector)
|
||||
goto error;
|
||||
return ERROR_FLASH_SECTOR_INVALID;
|
||||
|
||||
if (sector->is_protected)
|
||||
goto error;
|
||||
|
||||
@@ -43,9 +43,7 @@ static enum aice_target_endian data_endian;
|
||||
|
||||
/* Constants for AICE command format length */
|
||||
static const int32_t AICE_FORMAT_HTDA = 3;
|
||||
static const int32_t AICE_FORMAT_HTDB = 6;
|
||||
static const int32_t AICE_FORMAT_HTDC = 7;
|
||||
static const int32_t AICE_FORMAT_HTDD = 10;
|
||||
static const int32_t AICE_FORMAT_HTDMA = 4;
|
||||
static const int32_t AICE_FORMAT_HTDMB = 8;
|
||||
static const int32_t AICE_FORMAT_HTDMC = 8;
|
||||
@@ -57,26 +55,9 @@ static const int32_t AICE_FORMAT_DTHMB = 4;
|
||||
|
||||
/* Constants for AICE command */
|
||||
static const uint8_t AICE_CMD_SCAN_CHAIN = 0x00;
|
||||
static const uint8_t AICE_CMD_SELECT_TARGET = 0x01;
|
||||
static const uint8_t AICE_CMD_READ_DIM = 0x02;
|
||||
static const uint8_t AICE_CMD_READ_EDMSR = 0x03;
|
||||
static const uint8_t AICE_CMD_READ_DTR = 0x04;
|
||||
static const uint8_t AICE_CMD_READ_MEM = 0x05;
|
||||
static const uint8_t AICE_CMD_READ_MISC = 0x06;
|
||||
static const uint8_t AICE_CMD_FASTREAD_MEM = 0x07;
|
||||
static const uint8_t AICE_CMD_WRITE_DIM = 0x08;
|
||||
static const uint8_t AICE_CMD_WRITE_EDMSR = 0x09;
|
||||
static const uint8_t AICE_CMD_WRITE_DTR = 0x0A;
|
||||
static const uint8_t AICE_CMD_WRITE_MEM = 0x0B;
|
||||
static const uint8_t AICE_CMD_WRITE_MISC = 0x0C;
|
||||
static const uint8_t AICE_CMD_FASTWRITE_MEM = 0x0D;
|
||||
static const uint8_t AICE_CMD_EXECUTE = 0x0E;
|
||||
static const uint8_t AICE_CMD_READ_MEM_B = 0x14;
|
||||
static const uint8_t AICE_CMD_READ_MEM_H = 0x15;
|
||||
static const uint8_t AICE_CMD_T_READ_MISC = 0x20;
|
||||
static const uint8_t AICE_CMD_T_READ_EDMSR = 0x21;
|
||||
static const uint8_t AICE_CMD_T_READ_DTR = 0x22;
|
||||
static const uint8_t AICE_CMD_T_READ_DIM = 0x23;
|
||||
static const uint8_t AICE_CMD_T_READ_MEM_B = 0x24;
|
||||
static const uint8_t AICE_CMD_T_READ_MEM_H = 0x25;
|
||||
static const uint8_t AICE_CMD_T_READ_MEM = 0x26;
|
||||
@@ -89,11 +70,7 @@ static const uint8_t AICE_CMD_T_WRITE_MEM_B = 0x2C;
|
||||
static const uint8_t AICE_CMD_T_WRITE_MEM_H = 0x2D;
|
||||
static const uint8_t AICE_CMD_T_WRITE_MEM = 0x2E;
|
||||
static const uint8_t AICE_CMD_T_FASTWRITE_MEM = 0x2F;
|
||||
static const uint8_t AICE_CMD_T_GET_TRACE_STATUS = 0x36;
|
||||
static const uint8_t AICE_CMD_T_EXECUTE = 0x3E;
|
||||
static const uint8_t AICE_CMD_AICE_PROGRAM_READ = 0x40;
|
||||
static const uint8_t AICE_CMD_AICE_PROGRAM_WRITE = 0x41;
|
||||
static const uint8_t AICE_CMD_AICE_PROGRAM_CONTROL = 0x42;
|
||||
static const uint8_t AICE_CMD_READ_CTRL = 0x50;
|
||||
static const uint8_t AICE_CMD_WRITE_CTRL = 0x51;
|
||||
static const uint8_t AICE_CMD_BATCH_BUFFER_READ = 0x60;
|
||||
|
||||
@@ -7,7 +7,7 @@ libocdjtagdrivers_la_SOURCES = \
|
||||
$(DRIVERFILES)
|
||||
|
||||
libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) \
|
||||
$(LIBUSB0_CFLAGS) $(HIDAPI_CFLAGS)
|
||||
$(LIBUSB0_CFLAGS) $(HIDAPI_CFLAGS) $(LIBFTDI_CFLAGS)
|
||||
|
||||
ULINK_FIRMWARE = $(srcdir)/OpenULINK
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ static struct cable cables[] = {
|
||||
SOFT TDI - Target SRST
|
||||
*/
|
||||
{ "altium", 0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 },
|
||||
{ "aspo", 0x10, 0x01, 0x04, 0x08, 0x02, 0x10, 0x17, 0x00, 0x17, 0x17, 0x00 },
|
||||
{ NULL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
|
||||
@@ -29,10 +29,6 @@
|
||||
#include <jtag/interface.h>
|
||||
#include "bitbang.h"
|
||||
|
||||
#ifndef UNIX_PATH_LEN
|
||||
#define UNIX_PATH_LEN 108
|
||||
#endif
|
||||
|
||||
/* arbitrary limit on host name length: */
|
||||
#define REMOTE_BITBANG_HOST_MAX 255
|
||||
|
||||
@@ -192,8 +188,8 @@ static int remote_bitbang_init_unix(void)
|
||||
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, remote_bitbang_host, UNIX_PATH_LEN);
|
||||
addr.sun_path[UNIX_PATH_LEN-1] = '\0';
|
||||
strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));
|
||||
addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
|
||||
LOG_ERROR("connect: %s", strerror(errno));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include $(top_srcdir)/common.mk
|
||||
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS)
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libocdusbblaster.la
|
||||
libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC)
|
||||
|
||||
@@ -952,7 +952,7 @@ COMMAND_HANDLER(ublast_handle_pin_command)
|
||||
|
||||
if (strlen(pin_value) > 1)
|
||||
val = '?';
|
||||
switch (tolower(val)) {
|
||||
switch (tolower((unsigned char)val)) {
|
||||
case '0':
|
||||
*steer = FIXED_0;
|
||||
break;
|
||||
|
||||
118
src/svf/svf.c
118
src/svf/svf.c
@@ -241,6 +241,30 @@ static long svf_total_lines;
|
||||
static int svf_percentage;
|
||||
static int svf_last_printed_percentage = -1;
|
||||
|
||||
static int svf_realloc_buffers(size_t len)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = realloc(svf_tdi_buffer, len);
|
||||
if (!ptr)
|
||||
return ERROR_FAIL;
|
||||
svf_tdi_buffer = ptr;
|
||||
|
||||
ptr = realloc(svf_tdo_buffer, len);
|
||||
if (!ptr)
|
||||
return ERROR_FAIL;
|
||||
svf_tdo_buffer = ptr;
|
||||
|
||||
ptr = realloc(svf_mask_buffer, len);
|
||||
if (!ptr)
|
||||
return ERROR_FAIL;
|
||||
svf_mask_buffer = ptr;
|
||||
|
||||
svf_buffer_size = len;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void svf_free_xxd_para(struct svf_xxr_para *para)
|
||||
{
|
||||
if (NULL != para) {
|
||||
@@ -383,25 +407,10 @@ COMMAND_HANDLER(handle_svf_command)
|
||||
/* in case current command cannot be committed, and next command is a bit scan command */
|
||||
/* here is 32K bits for this big scan command, it should be enough */
|
||||
/* buffer will be reallocated if buffer size is not enough */
|
||||
svf_tdi_buffer = malloc(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT);
|
||||
if (NULL == svf_tdi_buffer) {
|
||||
LOG_ERROR("not enough memory");
|
||||
if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT) != ERROR_OK) {
|
||||
ret = ERROR_FAIL;
|
||||
goto free_all;
|
||||
}
|
||||
svf_tdo_buffer = malloc(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT);
|
||||
if (NULL == svf_tdo_buffer) {
|
||||
LOG_ERROR("not enough memory");
|
||||
ret = ERROR_FAIL;
|
||||
goto free_all;
|
||||
}
|
||||
svf_mask_buffer = malloc(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT);
|
||||
if (NULL == svf_mask_buffer) {
|
||||
LOG_ERROR("not enough memory");
|
||||
ret = ERROR_FAIL;
|
||||
goto free_all;
|
||||
}
|
||||
svf_buffer_size = 2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT;
|
||||
|
||||
memcpy(&svf_para, &svf_para_init, sizeof(svf_para));
|
||||
|
||||
@@ -1078,47 +1087,11 @@ XXR_common:
|
||||
i = svf_para.hdr_para.len + svf_para.sdr_para.len +
|
||||
svf_para.tdr_para.len;
|
||||
if ((svf_buffer_size - svf_buffer_index) < ((i + 7) >> 3)) {
|
||||
#if 1
|
||||
/* simply print error message */
|
||||
LOG_ERROR("buffer is not enough, report to author");
|
||||
return ERROR_FAIL;
|
||||
#else
|
||||
uint8_t *buffer_tmp;
|
||||
|
||||
/* reallocate buffer */
|
||||
buffer_tmp = malloc(svf_buffer_index + ((i + 7) >> 3));
|
||||
if (NULL == buffer_tmp) {
|
||||
if (svf_realloc_buffers(svf_buffer_index + ((i + 7) >> 3)) != ERROR_OK) {
|
||||
LOG_ERROR("not enough memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
memcpy(buffer_tmp, svf_tdi_buffer, svf_buffer_index);
|
||||
/* svf_tdi_buffer isn't NULL here */
|
||||
free(svf_tdi_buffer);
|
||||
svf_tdi_buffer = buffer_tmp;
|
||||
|
||||
buffer_tmp = malloc(svf_buffer_index + ((i + 7) >> 3));
|
||||
if (NULL == buffer_tmp) {
|
||||
LOG_ERROR("not enough memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
memcpy(buffer_tmp, svf_tdo_buffer, svf_buffer_index);
|
||||
/* svf_tdo_buffer isn't NULL here */
|
||||
free(svf_tdo_buffer);
|
||||
svf_tdo_buffer = buffer_tmp;
|
||||
|
||||
buffer_tmp = malloc(svf_buffer_index + ((i + 7) >> 3));
|
||||
if (NULL == buffer_tmp) {
|
||||
LOG_ERROR("not enough memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
memcpy(buffer_tmp, svf_mask_buffer, svf_buffer_index);
|
||||
/* svf_mask_buffer isn't NULL here */
|
||||
free(svf_mask_buffer);
|
||||
svf_mask_buffer = buffer_tmp;
|
||||
|
||||
buffer_tmp = NULL;
|
||||
svf_buffer_size = svf_buffer_index + ((i + 7) >> 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* assemble dr data */
|
||||
@@ -1205,47 +1178,10 @@ XXR_common:
|
||||
i = svf_para.hir_para.len + svf_para.sir_para.len +
|
||||
svf_para.tir_para.len;
|
||||
if ((svf_buffer_size - svf_buffer_index) < ((i + 7) >> 3)) {
|
||||
#if 1
|
||||
/* simply print error message */
|
||||
LOG_ERROR("buffer is not enough, report to author");
|
||||
return ERROR_FAIL;
|
||||
#else
|
||||
uint8_t *buffer_tmp;
|
||||
|
||||
/* reallocate buffer */
|
||||
buffer_tmp = malloc(svf_buffer_index + ((i + 7) >> 3));
|
||||
if (NULL == buffer_tmp) {
|
||||
if (svf_realloc_buffers(svf_buffer_index + ((i + 7) >> 3)) != ERROR_OK) {
|
||||
LOG_ERROR("not enough memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
memcpy(buffer_tmp, svf_tdi_buffer, svf_buffer_index);
|
||||
/* svf_tdi_buffer isn't NULL here */
|
||||
free(svf_tdi_buffer);
|
||||
svf_tdi_buffer = buffer_tmp;
|
||||
|
||||
buffer_tmp = malloc(svf_buffer_index + ((i + 7) >> 3));
|
||||
if (NULL == buffer_tmp) {
|
||||
LOG_ERROR("not enough memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
memcpy(buffer_tmp, svf_tdo_buffer, svf_buffer_index);
|
||||
/* svf_tdo_buffer isn't NULL here */
|
||||
free(svf_tdo_buffer);
|
||||
svf_tdo_buffer = buffer_tmp;
|
||||
|
||||
buffer_tmp = malloc(svf_buffer_index + ((i + 7) >> 3));
|
||||
if (NULL == buffer_tmp) {
|
||||
LOG_ERROR("not enough memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
memcpy(buffer_tmp, svf_mask_buffer, svf_buffer_index);
|
||||
/* svf_mask_buffer isn't NULL here */
|
||||
free(svf_mask_buffer);
|
||||
svf_mask_buffer = buffer_tmp;
|
||||
|
||||
buffer_tmp = NULL;
|
||||
svf_buffer_size = svf_buffer_index + ((i + 7) >> 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* assemble ir data */
|
||||
|
||||
@@ -58,8 +58,8 @@ enum arm_mode {
|
||||
ARM_MODE_FIQ = 17,
|
||||
ARM_MODE_IRQ = 18,
|
||||
ARM_MODE_SVC = 19,
|
||||
ARM_MODE_MON = 22,
|
||||
ARM_MODE_ABT = 23,
|
||||
ARM_MODE_MON = 26,
|
||||
ARM_MODE_UND = 27,
|
||||
ARM_MODE_SYS = 31,
|
||||
|
||||
|
||||
@@ -295,18 +295,39 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
|
||||
size_t nbytes = size * count;
|
||||
const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
|
||||
uint32_t csw_size;
|
||||
uint32_t addr_xor;
|
||||
int retval;
|
||||
|
||||
if (size == 4)
|
||||
/* TI BE-32 Quirks mode:
|
||||
* Writes on big-endian TMS570 behave very strangely. Observed behavior:
|
||||
* size write address bytes written in order
|
||||
* 4 TAR ^ 0 (val >> 24), (val >> 16), (val >> 8), (val)
|
||||
* 2 TAR ^ 2 (val >> 8), (val)
|
||||
* 1 TAR ^ 3 (val)
|
||||
* For example, if you attempt to write a single byte to address 0, the processor
|
||||
* will actually write a byte to address 3.
|
||||
*
|
||||
* To make writes of size < 4 work as expected, we xor a value with the address before
|
||||
* setting the TAP, and we set the TAP after every transfer rather then relying on
|
||||
* address increment. */
|
||||
|
||||
if (size == 4) {
|
||||
csw_size = CSW_32BIT;
|
||||
else if (size == 2)
|
||||
addr_xor = 0;
|
||||
} else if (size == 2) {
|
||||
csw_size = CSW_16BIT;
|
||||
else if (size == 1)
|
||||
addr_xor = dap->ti_be_32_quirks ? 2 : 0;
|
||||
} else if (size == 1) {
|
||||
csw_size = CSW_8BIT;
|
||||
else
|
||||
addr_xor = dap->ti_be_32_quirks ? 3 : 0;
|
||||
} else {
|
||||
return ERROR_TARGET_UNALIGNED_ACCESS;
|
||||
}
|
||||
|
||||
if (dap->unaligned_access_bad && (address % size != 0))
|
||||
return ERROR_TARGET_UNALIGNED_ACCESS;
|
||||
|
||||
retval = dap_setup_accessport_tar(dap, address);
|
||||
retval = dap_setup_accessport_tar(dap, address ^ addr_xor);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
@@ -328,14 +349,32 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
|
||||
/* How many source bytes each transfer will consume, and their location in the DRW,
|
||||
* depends on the type of transfer and alignment. See ARM document IHI0031C. */
|
||||
uint32_t outvalue = 0;
|
||||
switch (this_size) {
|
||||
case 4:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
case 2:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
case 1:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
if (dap->ti_be_32_quirks) {
|
||||
switch (this_size) {
|
||||
case 4:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
|
||||
break;
|
||||
case 2:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
|
||||
break;
|
||||
case 1:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (address++ & 3) ^ addr_xor);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (this_size) {
|
||||
case 4:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
case 2:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
case 1:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
}
|
||||
}
|
||||
|
||||
nbytes -= this_size;
|
||||
@@ -344,9 +383,9 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
|
||||
/* Rewrite TAR if it wrapped */
|
||||
if (addrinc && address % dap->tar_autoincr_block < size && nbytes > 0) {
|
||||
retval = dap_setup_accessport_tar(dap, address);
|
||||
/* Rewrite TAR if it wrapped or we're xoring addresses */
|
||||
if (addrinc && (addr_xor || (address % dap->tar_autoincr_block < size && nbytes > 0))) {
|
||||
retval = dap_setup_accessport_tar(dap, address ^ addr_xor);
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
}
|
||||
@@ -389,6 +428,13 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
|
||||
uint32_t address = adr;
|
||||
int retval;
|
||||
|
||||
/* TI BE-32 Quirks mode:
|
||||
* Reads on big-endian TMS570 behave strangely differently than writes.
|
||||
* They read from the physical address requested, but with DRW byte-reversed.
|
||||
* For example, a byte read from address 0 will place the result in the high bytes of DRW.
|
||||
* Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,
|
||||
* so avoid them. */
|
||||
|
||||
if (size == 4)
|
||||
csw_size = CSW_32BIT;
|
||||
else if (size == 2)
|
||||
@@ -398,6 +444,9 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
|
||||
else
|
||||
return ERROR_TARGET_UNALIGNED_ACCESS;
|
||||
|
||||
if (dap->unaligned_access_bad && (adr % size != 0))
|
||||
return ERROR_TARGET_UNALIGNED_ACCESS;
|
||||
|
||||
/* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant
|
||||
* over-allocation if packed transfers are going to be used, but determining the real need at
|
||||
* this point would be messy. */
|
||||
@@ -478,14 +527,26 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
|
||||
this_size = 4;
|
||||
}
|
||||
|
||||
switch (this_size) {
|
||||
case 4:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
case 2:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
case 1:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
if (dap->ti_be_32_quirks) {
|
||||
switch (this_size) {
|
||||
case 4:
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
case 2:
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
case 1:
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
}
|
||||
} else {
|
||||
switch (this_size) {
|
||||
case 4:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
case 2:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
case 1:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
}
|
||||
}
|
||||
|
||||
read_ptr++;
|
||||
@@ -845,7 +906,7 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
|
||||
dap_syssec(dap);
|
||||
|
||||
/* check that we support packed transfers */
|
||||
uint32_t csw;
|
||||
uint32_t csw, cfg;
|
||||
|
||||
retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
|
||||
if (retval != ERROR_OK)
|
||||
@@ -855,6 +916,10 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = dap_queue_ap_read(dap, AP_REG_CFG, &cfg);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = dap_run(dap);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
@@ -864,9 +929,25 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
|
||||
else
|
||||
dap->packed_transfers = false;
|
||||
|
||||
/* Packed transfers on TI BE-32 processors do not work correctly in
|
||||
* many cases. */
|
||||
if (dap->ti_be_32_quirks)
|
||||
dap->packed_transfers = false;
|
||||
|
||||
LOG_DEBUG("MEM_AP Packed Transfers: %s",
|
||||
dap->packed_transfers ? "enabled" : "disabled");
|
||||
|
||||
/* The ARM ADI spec leaves implementation-defined whether unaligned
|
||||
* memory accesses work, only work partially, or cause a sticky error.
|
||||
* On TI BE-32 processors, reads seem to return garbage in some bytes
|
||||
* and unaligned writes seem to cause a sticky error.
|
||||
* TODO: it would be nice to have a way to detect whether unaligned
|
||||
* operations are supported on other processors. */
|
||||
dap->unaligned_access_bad = dap->ti_be_32_quirks;
|
||||
|
||||
LOG_DEBUG("MEM_AP CFG: large data %d, long address %d, big-endian %d",
|
||||
!!(cfg & 0x04), !!(cfg & 0x02), !!(cfg & 0x01));
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@@ -1664,6 +1745,32 @@ COMMAND_HANDLER(dap_apid_command)
|
||||
return retval;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(dap_ti_be_32_quirks_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
uint32_t enable = dap->ti_be_32_quirks;
|
||||
|
||||
switch (CMD_ARGC) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable);
|
||||
if (enable > 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
break;
|
||||
default:
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
dap->ti_be_32_quirks = enable;
|
||||
command_print(CMD_CTX, "TI BE-32 quirks mode %s",
|
||||
enable ? "enabled" : "disabled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct command_registration dap_commands[] = {
|
||||
{
|
||||
.name = "info",
|
||||
@@ -1713,6 +1820,13 @@ static const struct command_registration dap_commands[] = {
|
||||
"bus access [0-255]",
|
||||
.usage = "[cycles]",
|
||||
},
|
||||
{
|
||||
.name = "ti_be_32_quirks",
|
||||
.handler = dap_ti_be_32_quirks_command,
|
||||
.mode = COMMAND_CONFIG,
|
||||
.help = "set/get quirks mode for TI TMS450/TMS570 processors",
|
||||
.usage = "[enable]",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
|
||||
@@ -189,6 +189,15 @@ struct adiv5_dap {
|
||||
|
||||
/* true if packed transfers are supported by the MEM-AP */
|
||||
bool packed_transfers;
|
||||
|
||||
/* true if unaligned memory access is not supported by the MEM-AP */
|
||||
bool unaligned_access_bad;
|
||||
|
||||
/* The TI TMS470 and TMS570 series processors use a BE-32 memory ordering
|
||||
* despite lack of support in the ARMv7 architecture. Memory access through
|
||||
* the AHB-AP has strange byte ordering these processors, and we need to
|
||||
* swizzle appropriately. */
|
||||
bool ti_be_32_quirks;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -178,7 +178,7 @@ static struct reg_cache *avr32_build_reg_cache(struct target *target)
|
||||
struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
|
||||
struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
|
||||
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
||||
struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
|
||||
struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
|
||||
struct avr32_core_reg *arch_info =
|
||||
malloc(sizeof(struct avr32_core_reg) * num_regs);
|
||||
int i;
|
||||
|
||||
@@ -766,7 +766,7 @@ static int cortex_a8_halt_smp(struct target *target)
|
||||
static int update_halt_gdb(struct target *target)
|
||||
{
|
||||
int retval = 0;
|
||||
if (target->gdb_service->core[0] == -1) {
|
||||
if (target->gdb_service && target->gdb_service->core[0] == -1) {
|
||||
target->gdb_service->target = target;
|
||||
target->gdb_service->core[0] = target->coreid;
|
||||
retval += cortex_a8_halt_smp(target);
|
||||
|
||||
@@ -451,7 +451,7 @@ static void dsp563xx_build_reg_cache(struct target *target)
|
||||
|
||||
struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
|
||||
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
||||
struct reg *reg_list = malloc(sizeof(struct reg) * DSP563XX_NUMCOREREGS);
|
||||
struct reg *reg_list = calloc(DSP563XX_NUMCOREREGS, sizeof(struct reg));
|
||||
struct dsp563xx_core_reg *arch_info = malloc(
|
||||
sizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS);
|
||||
int i;
|
||||
|
||||
@@ -375,7 +375,7 @@ struct reg_cache *lakemont_build_reg_cache(struct target *t)
|
||||
int num_regs = ARRAY_SIZE(regs);
|
||||
struct reg_cache **cache_p = register_get_last_cache_p(&t->reg_cache);
|
||||
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
||||
struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
|
||||
struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
|
||||
struct lakemont_core_reg *arch_info = malloc(sizeof(struct lakemont_core_reg) * num_regs);
|
||||
struct reg_feature *feature;
|
||||
int i;
|
||||
|
||||
@@ -252,7 +252,7 @@ struct reg_cache *mips32_build_reg_cache(struct target *target)
|
||||
int num_regs = MIPS32NUMCOREREGS;
|
||||
struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
|
||||
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
||||
struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
|
||||
struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
|
||||
struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
|
||||
int i;
|
||||
|
||||
|
||||
@@ -513,7 +513,7 @@ static struct reg_cache *or1k_build_reg_cache(struct target *target)
|
||||
struct or1k_common *or1k = target_to_or1k(target);
|
||||
struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
|
||||
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
|
||||
struct reg *reg_list = malloc((or1k->nb_regs) * sizeof(struct reg));
|
||||
struct reg *reg_list = calloc(or1k->nb_regs, sizeof(struct reg));
|
||||
struct or1k_core_reg *arch_info =
|
||||
malloc((or1k->nb_regs) * sizeof(struct or1k_core_reg));
|
||||
struct reg_feature *feature;
|
||||
|
||||
@@ -670,6 +670,7 @@ int x86_32_common_read_io(struct target *t, uint32_t addr,
|
||||
/* if CS.D bit=1 then its a 32 bit code segment, else 16 */
|
||||
bool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D;
|
||||
int retval = ERROR_FAIL;
|
||||
bool pg_disabled = false;
|
||||
LOG_DEBUG("addr=%08" PRIx32 ", size=%d, buf=%p", addr, size, buf);
|
||||
check_not_halted(t);
|
||||
if (!buf || !addr) {
|
||||
@@ -681,6 +682,13 @@ int x86_32_common_read_io(struct target *t, uint32_t addr,
|
||||
LOG_ERROR("%s error EDX write", __func__);
|
||||
return retval;
|
||||
}
|
||||
/* to access physical memory, switch off the CR0.PG bit */
|
||||
if (x86_32->is_paging_enabled(t)) {
|
||||
retval = x86_32->disable_paging(t);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
pg_disabled = true;
|
||||
}
|
||||
switch (size) {
|
||||
case BYTE:
|
||||
if (use32)
|
||||
@@ -704,6 +712,13 @@ int x86_32_common_read_io(struct target *t, uint32_t addr,
|
||||
LOG_ERROR("%s invalid read io size", __func__);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
/* restore CR0.PG bit if needed */
|
||||
if (pg_disabled) {
|
||||
retval = x86_32->enable_paging(t);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
pg_disabled = false;
|
||||
}
|
||||
uint32_t regval = 0;
|
||||
retval = x86_32->read_hw_reg(t, EAX, ®val, 0);
|
||||
if (retval != ERROR_OK) {
|
||||
@@ -729,6 +744,7 @@ int x86_32_common_write_io(struct target *t, uint32_t addr,
|
||||
LOG_DEBUG("addr=%08" PRIx32 ", size=%d, buf=%p", addr, size, buf);
|
||||
check_not_halted(t);
|
||||
int retval = ERROR_FAIL;
|
||||
bool pg_disabled = false;
|
||||
if (!buf || !addr) {
|
||||
LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32, __func__, buf, addr);
|
||||
return retval;
|
||||
@@ -747,6 +763,13 @@ int x86_32_common_write_io(struct target *t, uint32_t addr,
|
||||
LOG_ERROR("%s error on EAX write", __func__);
|
||||
return retval;
|
||||
}
|
||||
/* to access physical memory, switch off the CR0.PG bit */
|
||||
if (x86_32->is_paging_enabled(t)) {
|
||||
retval = x86_32->disable_paging(t);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
pg_disabled = true;
|
||||
}
|
||||
switch (size) {
|
||||
case BYTE:
|
||||
if (use32)
|
||||
@@ -770,6 +793,13 @@ int x86_32_common_write_io(struct target *t, uint32_t addr,
|
||||
LOG_ERROR("%s invalid write io size", __func__);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
/* restore CR0.PG bit if needed */
|
||||
if (pg_disabled) {
|
||||
retval = x86_32->enable_paging(t);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
pg_disabled = false;
|
||||
}
|
||||
retval = x86_32->transaction_status(t);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("%s error on io write", __func__);
|
||||
|
||||
15
tcl/board/bt-homehubv1.cfg
Normal file
15
tcl/board/bt-homehubv1.cfg
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# BT HomeHub v1
|
||||
#
|
||||
|
||||
set partition_list {
|
||||
CFE { Bootloader 0xbe400000 0x00020000 }
|
||||
firmware { "Kernel+rootfs" 0xbe420000 0x007d0000 }
|
||||
fisdir { "FIS Directory" 0xbebf0000 0x0000f000 }
|
||||
nvram { "Config space" 0xbebff000 0x00001000 }
|
||||
}
|
||||
|
||||
source [find target/bcm6348.cfg]
|
||||
|
||||
set _FLASHNAME $_CHIPNAME.norflash
|
||||
flash bank $_FLASHNAME cfi 0xbe400000 0x00800000 2 2 $_TARGETNAME
|
||||
9
tcl/target/bcm6348.cfg
Normal file
9
tcl/target/bcm6348.cfg
Normal file
@@ -0,0 +1,9 @@
|
||||
set _CHIPNAME bcm6348
|
||||
set _CPUID 0x0634817f
|
||||
|
||||
adapter_khz 1000
|
||||
|
||||
jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME
|
||||
@@ -40,6 +40,9 @@ set _TARGETNAME $_CHIPNAME.cpu
|
||||
target create $_TARGETNAME cortex_r4 -endian $_ENDIAN \
|
||||
-chain-position $_CHIPNAME.dap -coreid 0 -dbgbase 0x00001003
|
||||
|
||||
# TMS570 uses quirky BE-32 mode
|
||||
$_TARGETNAME dap ti_be_32_quirks 1
|
||||
|
||||
$_TARGETNAME configure -event gdb-attach {
|
||||
cortex_r4 dbginit
|
||||
halt
|
||||
|
||||
@@ -5,6 +5,7 @@ set known_boards {
|
||||
"asus-rt-n16 ASUS RT-N16"
|
||||
"linksys-wrt54gl Linksys WRT54GL v1.1"
|
||||
"netgear-dg834v3 Netgear DG834G v3"
|
||||
"bt-homehubv1 BT HomeHub v1"
|
||||
}
|
||||
|
||||
proc firmware_help { } {
|
||||
|
||||
Reference in New Issue
Block a user