From Michael Bruck
- bugfix in server.c - removed unused parameter from jtag_add_ir_scan et al. This wasn't necessary in hindsight but anyway. - arm11 source committed but not not in Makefile.am/target.c for now. git-svn-id: svn://svn.berlios.de/openocd/trunk@341 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
4edcbe0a54
commit
687a9553c9
2696
src/flash/str9xpec.c
2696
src/flash/str9xpec.c
File diff suppressed because it is too large
Load Diff
3641
src/jtag/jtag.c
3641
src/jtag/jtag.c
File diff suppressed because it is too large
Load Diff
654
src/jtag/jtag.h
654
src/jtag/jtag.h
|
@ -1,327 +1,327 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef JTAG_H
|
||||
#define JTAG_H
|
||||
|
||||
#include "types.h"
|
||||
#include "binarybuffer.h"
|
||||
|
||||
#include "command.h"
|
||||
|
||||
#if 0
|
||||
#define _DEBUG_JTAG_IO_
|
||||
#endif
|
||||
|
||||
/* Tap States
|
||||
* TLR - Test-Logic-Reset, RTI - Run-Test/Idle,
|
||||
* SDS - Select-DR-Scan, CD - Capture-DR, SD - Shift-DR, E1D - Exit1-DR,
|
||||
* PD - Pause-DR, E2D - Exit2-DR, UD - Update-DR,
|
||||
* SIS - Select-IR-Scan, CI - Capture-IR, SI - Shift-IR, E1I - Exit1-IR,
|
||||
* PI - Pause-IR, E2I - Exit2-IR, UI - Update-IR
|
||||
*/
|
||||
enum tap_state
|
||||
{
|
||||
TAP_TLR = 0x0, TAP_RTI = 0x8,
|
||||
TAP_SDS = 0x1, TAP_CD = 0x2, TAP_SD = 0x3, TAP_E1D = 0x4,
|
||||
TAP_PD = 0x5, TAP_E2D = 0x6, TAP_UD = 0x7,
|
||||
TAP_SIS = 0x9, TAP_CI = 0xa, TAP_SI = 0xb, TAP_E1I = 0xc,
|
||||
TAP_PI = 0xd, TAP_E2I = 0xe, TAP_UI = 0xf
|
||||
};
|
||||
|
||||
typedef struct tap_transition_s
|
||||
{
|
||||
enum tap_state high;
|
||||
enum tap_state low;
|
||||
} tap_transition_t;
|
||||
|
||||
extern char* tap_state_strings[16];
|
||||
extern int tap_move_map[16]; /* map 16 TAP states to 6 stable states */
|
||||
extern u8 tap_move[6][6]; /* value scanned to TMS to move from one of six stable states to another */
|
||||
extern tap_transition_t tap_transitions[16]; /* describe the TAP state diagram */
|
||||
|
||||
extern enum tap_state end_state; /* finish DR scans in dr_end_state */
|
||||
extern enum tap_state cur_state; /* current TAP state */
|
||||
|
||||
extern enum tap_state cmd_queue_end_state; /* finish DR scans in dr_end_state */
|
||||
extern enum tap_state cmd_queue_cur_state; /* current TAP state */
|
||||
|
||||
#define TAP_MOVE(from, to) tap_move[tap_move_map[from]][tap_move_map[to]]
|
||||
|
||||
typedef void * error_handler_t; /* Later on we can delete error_handler_t, but keep it for now to make patches more readable */
|
||||
|
||||
struct scan_field_s;
|
||||
typedef int (*in_handler_t)(u8 *in_value, void *priv, struct scan_field_s *field);
|
||||
|
||||
typedef struct scan_field_s
|
||||
{
|
||||
int device; /* ordinal device number this instruction refers to */
|
||||
int num_bits; /* number of bits this field specifies (up to 32) */
|
||||
u8 *out_value; /* value to be scanned into the device */
|
||||
u8 *out_mask; /* only masked bits care */
|
||||
u8 *in_value; /* pointer to a 32-bit memory location to take data scanned out */
|
||||
/* in_check_value/mask, in_handler_error_handler, in_handler_priv can be used by the in handler, otherwise they contain garbage */
|
||||
u8 *in_check_value; /* used to validate scan results */
|
||||
u8 *in_check_mask; /* check specified bits against check_value */
|
||||
in_handler_t in_handler; /* process received buffer using this handler */
|
||||
void *in_handler_priv; /* additional information for the in_handler */
|
||||
} scan_field_t;
|
||||
|
||||
enum scan_type
|
||||
{
|
||||
/* IN: from device to host, OUT: from host to device */
|
||||
SCAN_IN = 1, SCAN_OUT = 2, SCAN_IO = 3
|
||||
};
|
||||
|
||||
typedef struct scan_command_s
|
||||
{
|
||||
int ir_scan; /* instruction/not data scan */
|
||||
int num_fields; /* number of fields in *fields array */
|
||||
scan_field_t *fields; /* pointer to an array of data scan fields */
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} scan_command_t;
|
||||
|
||||
typedef struct statemove_command_s
|
||||
{
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} statemove_command_t;
|
||||
|
||||
typedef struct pathmove_command_s
|
||||
{
|
||||
int num_states; /* number of states in *path */
|
||||
enum tap_state *path; /* states that have to be passed */
|
||||
} pathmove_command_t;
|
||||
|
||||
typedef struct runtest_command_s
|
||||
{
|
||||
int num_cycles; /* number of cycles that should be spent in Run-Test/Idle */
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} runtest_command_t;
|
||||
|
||||
typedef struct reset_command_s
|
||||
{
|
||||
int trst; /* trst/srst 0: deassert, 1: assert, -1: don't change */
|
||||
int srst;
|
||||
} reset_command_t;
|
||||
|
||||
typedef struct end_state_command_s
|
||||
{
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} end_state_command_t;
|
||||
|
||||
typedef struct sleep_command_s
|
||||
{
|
||||
u32 us; /* number of microseconds to sleep */
|
||||
} sleep_command_t;
|
||||
|
||||
typedef union jtag_command_container_u
|
||||
{
|
||||
scan_command_t *scan;
|
||||
statemove_command_t *statemove;
|
||||
pathmove_command_t *pathmove;
|
||||
runtest_command_t *runtest;
|
||||
reset_command_t *reset;
|
||||
end_state_command_t *end_state;
|
||||
sleep_command_t *sleep;
|
||||
} jtag_command_container_t;
|
||||
|
||||
enum jtag_command_type
|
||||
{
|
||||
JTAG_SCAN = 1,
|
||||
JTAG_STATEMOVE = 2, JTAG_RUNTEST = 3,
|
||||
JTAG_RESET = 4, JTAG_END_STATE = 5,
|
||||
JTAG_PATHMOVE = 6, JTAG_SLEEP = 7
|
||||
};
|
||||
|
||||
typedef struct jtag_command_s
|
||||
{
|
||||
jtag_command_container_t cmd;
|
||||
enum jtag_command_type type;
|
||||
struct jtag_command_s *next;
|
||||
} jtag_command_t;
|
||||
|
||||
extern jtag_command_t *jtag_command_queue;
|
||||
|
||||
typedef struct jtag_device_s
|
||||
{
|
||||
int ir_length; /* size of instruction register */
|
||||
u8 *expected; /* Capture-IR expected value */
|
||||
u8 *expected_mask; /* Capture-IR expected mask */
|
||||
u32 idcode; /* device identification code */
|
||||
u8 *cur_instr; /* current instruction */
|
||||
int bypass; /* bypass register selected */
|
||||
struct jtag_device_s *next;
|
||||
} jtag_device_t;
|
||||
|
||||
extern jtag_device_t *jtag_devices;
|
||||
extern int jtag_num_devices;
|
||||
extern int jtag_ir_scan_size;
|
||||
|
||||
enum reset_line_mode
|
||||
{
|
||||
LINE_OPEN_DRAIN = 0x0,
|
||||
LINE_PUSH_PULL = 0x1,
|
||||
};
|
||||
|
||||
typedef struct jtag_interface_s
|
||||
{
|
||||
char* name;
|
||||
|
||||
/* queued command execution
|
||||
*/
|
||||
int (*execute_queue)(void);
|
||||
|
||||
/* interface initalization
|
||||
*/
|
||||
int (*speed)(int speed);
|
||||
int (*register_commands)(struct command_context_s *cmd_ctx);
|
||||
int (*init)(void);
|
||||
int (*quit)(void);
|
||||
|
||||
} jtag_interface_t;
|
||||
|
||||
enum jtag_event
|
||||
{
|
||||
JTAG_SRST_ASSERTED,
|
||||
JTAG_TRST_ASSERTED,
|
||||
JTAG_SRST_RELEASED,
|
||||
JTAG_TRST_RELEASED,
|
||||
};
|
||||
|
||||
extern char* jtag_event_strings[];
|
||||
|
||||
extern int jtag_trst;
|
||||
extern int jtag_srst;
|
||||
|
||||
typedef struct jtag_event_callback_s
|
||||
{
|
||||
int (*callback)(enum jtag_event event, void *priv);
|
||||
void *priv;
|
||||
struct jtag_event_callback_s *next;
|
||||
} jtag_event_callback_t;
|
||||
|
||||
extern jtag_event_callback_t *jtag_event_callbacks;
|
||||
|
||||
extern jtag_interface_t *jtag; /* global pointer to configured JTAG interface */
|
||||
extern enum tap_state end_state;
|
||||
extern enum tap_state cur_state;
|
||||
|
||||
extern char* jtag_interface;
|
||||
extern int jtag_speed;
|
||||
|
||||
enum reset_types
|
||||
{
|
||||
RESET_NONE = 0x0,
|
||||
RESET_HAS_TRST = 0x1,
|
||||
RESET_HAS_SRST = 0x2,
|
||||
RESET_TRST_AND_SRST = 0x3,
|
||||
RESET_SRST_PULLS_TRST = 0x4,
|
||||
RESET_TRST_PULLS_SRST = 0x8,
|
||||
RESET_TRST_OPEN_DRAIN = 0x10,
|
||||
RESET_SRST_PUSH_PULL = 0x20,
|
||||
};
|
||||
|
||||
extern enum reset_types jtag_reset_config;
|
||||
|
||||
/* JTAG subsystem */
|
||||
extern int jtag_init(struct command_context_s *cmd_ctx);
|
||||
extern int jtag_register_commands(struct command_context_s *cmd_ctx);
|
||||
|
||||
/* JTAG interface, can be implemented with a software or hardware fifo */
|
||||
extern int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism);
|
||||
extern int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism);
|
||||
extern int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism);
|
||||
extern int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism);
|
||||
/* execute a state transition within the JTAG standard, but the exact path
|
||||
* path that is taken is undefined. Many implementations use precisely
|
||||
* 7 clocks to perform a transition, but it could be more or less
|
||||
* than that.
|
||||
*
|
||||
* The following assertions are made about certain common state moves:
|
||||
*
|
||||
* - A state move from Pause-[ID]R to Pause-[ID]R should always go through
|
||||
* Update-[ID]R and Capture-[ID]R before returning to Pause-[ID]R, otherwise
|
||||
* there's no way force a register update, if you can't go to Run-Test/Idle for
|
||||
* some reason.
|
||||
*
|
||||
* - A state move from Pause-[ID]R to Shift-[ID]R must not go through
|
||||
* Update-[ID]R.
|
||||
*
|
||||
* - Run-Test/Idle must not be entered unless requested, because R-T/I may have
|
||||
* side effects.
|
||||
*/
|
||||
extern int jtag_add_statemove(enum tap_state endstate);
|
||||
/* A list of unambigious single clock state transitions, not
|
||||
* all drivers can support this, but it is required for e.g.
|
||||
* XScale and Xilinx support
|
||||
*/
|
||||
extern int jtag_add_pathmove(int num_states, enum tap_state *path);
|
||||
/* cycle precisely num_cycles in the TAP_RTI state */
|
||||
extern int jtag_add_runtest(int num_cycles, enum tap_state endstate);
|
||||
extern int jtag_add_reset(int trst, int srst);
|
||||
extern int jtag_add_end_state(enum tap_state endstate);
|
||||
extern int jtag_add_sleep(u32 us);
|
||||
/*
|
||||
* For software FIFO implementations, the queued commands can be executed
|
||||
* during this call or earlier. A sw queue might decide to push out
|
||||
* some of the jtag_add_xxx() operations once the queue is "big enough".
|
||||
*
|
||||
* This fn will return an error code if any of the prior jtag_add_xxx()
|
||||
* calls caused a failure, e.g. check failure. Note that it does not
|
||||
* matter if the operation was executed *before* jtag_execute_queue(),
|
||||
* jtag_execute_queue() will still return an error code.
|
||||
*
|
||||
* All jtag_add_xxx() calls that have in_handler!=NULL will have been
|
||||
* executed when this fn returns, but if what has been queued only
|
||||
* clocks data out, without reading anything back, then JTAG could
|
||||
* be running *after* jtag_execute_queue() returns. The API does
|
||||
* not define a way to flush a hw FIFO that runs *after*
|
||||
* jtag_execute_queue() returns.
|
||||
*
|
||||
* jtag_add_xxx() commands can either be executed immediately or
|
||||
* at some time between the jtag_add_xxx() fn call and jtag_execute_queue().
|
||||
*/
|
||||
extern int jtag_execute_queue(void);
|
||||
|
||||
/* JTAG support functions */
|
||||
extern void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler);
|
||||
extern enum scan_type jtag_scan_type(scan_command_t *cmd);
|
||||
extern int jtag_scan_size(scan_command_t *cmd);
|
||||
extern int jtag_read_buffer(u8 *buffer, scan_command_t *cmd);
|
||||
extern int jtag_build_buffer(scan_command_t *cmd, u8 **buffer);
|
||||
extern jtag_device_t* jtag_get_device(int num);
|
||||
extern void jtag_sleep(u32 us);
|
||||
extern int jtag_call_event_callbacks(enum jtag_event event);
|
||||
extern int jtag_register_event_callback(int (*callback)(enum jtag_event event, void *priv), void *priv);
|
||||
|
||||
extern int jtag_verify_capture_ir;
|
||||
|
||||
|
||||
/* error codes
|
||||
* JTAG subsystem uses codes between -100 and -199 */
|
||||
|
||||
#define ERROR_JTAG_INIT_FAILED (-100)
|
||||
#define ERROR_JTAG_INVALID_INTERFACE (-101)
|
||||
#define ERROR_JTAG_NOT_IMPLEMENTED (-102)
|
||||
#define ERROR_JTAG_TRST_ASSERTED (-103)
|
||||
#define ERROR_JTAG_QUEUE_FAILED (-104)
|
||||
#define ERROR_JTAG_RESET_WOULD_ASSERT_TRST (-105)
|
||||
#define ERROR_JTAG_RESET_CANT_SRST (-106)
|
||||
#define ERROR_JTAG_DEVICE_ERROR (-107)
|
||||
#endif /* JTAG_H */
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef JTAG_H
|
||||
#define JTAG_H
|
||||
|
||||
#include "types.h"
|
||||
#include "binarybuffer.h"
|
||||
|
||||
#include "command.h"
|
||||
|
||||
#if 0
|
||||
#define _DEBUG_JTAG_IO_
|
||||
#endif
|
||||
|
||||
/* Tap States
|
||||
* TLR - Test-Logic-Reset, RTI - Run-Test/Idle,
|
||||
* SDS - Select-DR-Scan, CD - Capture-DR, SD - Shift-DR, E1D - Exit1-DR,
|
||||
* PD - Pause-DR, E2D - Exit2-DR, UD - Update-DR,
|
||||
* SIS - Select-IR-Scan, CI - Capture-IR, SI - Shift-IR, E1I - Exit1-IR,
|
||||
* PI - Pause-IR, E2I - Exit2-IR, UI - Update-IR
|
||||
*/
|
||||
enum tap_state
|
||||
{
|
||||
TAP_TLR = 0x0, TAP_RTI = 0x8,
|
||||
TAP_SDS = 0x1, TAP_CD = 0x2, TAP_SD = 0x3, TAP_E1D = 0x4,
|
||||
TAP_PD = 0x5, TAP_E2D = 0x6, TAP_UD = 0x7,
|
||||
TAP_SIS = 0x9, TAP_CI = 0xa, TAP_SI = 0xb, TAP_E1I = 0xc,
|
||||
TAP_PI = 0xd, TAP_E2I = 0xe, TAP_UI = 0xf
|
||||
};
|
||||
|
||||
typedef struct tap_transition_s
|
||||
{
|
||||
enum tap_state high;
|
||||
enum tap_state low;
|
||||
} tap_transition_t;
|
||||
|
||||
extern char* tap_state_strings[16];
|
||||
extern int tap_move_map[16]; /* map 16 TAP states to 6 stable states */
|
||||
extern u8 tap_move[6][6]; /* value scanned to TMS to move from one of six stable states to another */
|
||||
extern tap_transition_t tap_transitions[16]; /* describe the TAP state diagram */
|
||||
|
||||
extern enum tap_state end_state; /* finish DR scans in dr_end_state */
|
||||
extern enum tap_state cur_state; /* current TAP state */
|
||||
|
||||
extern enum tap_state cmd_queue_end_state; /* finish DR scans in dr_end_state */
|
||||
extern enum tap_state cmd_queue_cur_state; /* current TAP state */
|
||||
|
||||
#define TAP_MOVE(from, to) tap_move[tap_move_map[from]][tap_move_map[to]]
|
||||
|
||||
typedef void * error_handler_t; /* Later on we can delete error_handler_t, but keep it for now to make patches more readable */
|
||||
|
||||
struct scan_field_s;
|
||||
typedef int (*in_handler_t)(u8 *in_value, void *priv, struct scan_field_s *field);
|
||||
|
||||
typedef struct scan_field_s
|
||||
{
|
||||
int device; /* ordinal device number this instruction refers to */
|
||||
int num_bits; /* number of bits this field specifies (up to 32) */
|
||||
u8 *out_value; /* value to be scanned into the device */
|
||||
u8 *out_mask; /* only masked bits care */
|
||||
u8 *in_value; /* pointer to a 32-bit memory location to take data scanned out */
|
||||
/* in_check_value/mask, in_handler_error_handler, in_handler_priv can be used by the in handler, otherwise they contain garbage */
|
||||
u8 *in_check_value; /* used to validate scan results */
|
||||
u8 *in_check_mask; /* check specified bits against check_value */
|
||||
in_handler_t in_handler; /* process received buffer using this handler */
|
||||
void *in_handler_priv; /* additional information for the in_handler */
|
||||
} scan_field_t;
|
||||
|
||||
enum scan_type
|
||||
{
|
||||
/* IN: from device to host, OUT: from host to device */
|
||||
SCAN_IN = 1, SCAN_OUT = 2, SCAN_IO = 3
|
||||
};
|
||||
|
||||
typedef struct scan_command_s
|
||||
{
|
||||
int ir_scan; /* instruction/not data scan */
|
||||
int num_fields; /* number of fields in *fields array */
|
||||
scan_field_t *fields; /* pointer to an array of data scan fields */
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} scan_command_t;
|
||||
|
||||
typedef struct statemove_command_s
|
||||
{
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} statemove_command_t;
|
||||
|
||||
typedef struct pathmove_command_s
|
||||
{
|
||||
int num_states; /* number of states in *path */
|
||||
enum tap_state *path; /* states that have to be passed */
|
||||
} pathmove_command_t;
|
||||
|
||||
typedef struct runtest_command_s
|
||||
{
|
||||
int num_cycles; /* number of cycles that should be spent in Run-Test/Idle */
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} runtest_command_t;
|
||||
|
||||
typedef struct reset_command_s
|
||||
{
|
||||
int trst; /* trst/srst 0: deassert, 1: assert, -1: don't change */
|
||||
int srst;
|
||||
} reset_command_t;
|
||||
|
||||
typedef struct end_state_command_s
|
||||
{
|
||||
enum tap_state end_state; /* TAP state in which JTAG commands should finish */
|
||||
} end_state_command_t;
|
||||
|
||||
typedef struct sleep_command_s
|
||||
{
|
||||
u32 us; /* number of microseconds to sleep */
|
||||
} sleep_command_t;
|
||||
|
||||
typedef union jtag_command_container_u
|
||||
{
|
||||
scan_command_t *scan;
|
||||
statemove_command_t *statemove;
|
||||
pathmove_command_t *pathmove;
|
||||
runtest_command_t *runtest;
|
||||
reset_command_t *reset;
|
||||
end_state_command_t *end_state;
|
||||
sleep_command_t *sleep;
|
||||
} jtag_command_container_t;
|
||||
|
||||
enum jtag_command_type
|
||||
{
|
||||
JTAG_SCAN = 1,
|
||||
JTAG_STATEMOVE = 2, JTAG_RUNTEST = 3,
|
||||
JTAG_RESET = 4, JTAG_END_STATE = 5,
|
||||
JTAG_PATHMOVE = 6, JTAG_SLEEP = 7
|
||||
};
|
||||
|
||||
typedef struct jtag_command_s
|
||||
{
|
||||
jtag_command_container_t cmd;
|
||||
enum jtag_command_type type;
|
||||
struct jtag_command_s *next;
|
||||
} jtag_command_t;
|
||||
|
||||
extern jtag_command_t *jtag_command_queue;
|
||||
|
||||
typedef struct jtag_device_s
|
||||
{
|
||||
int ir_length; /* size of instruction register */
|
||||
u8 *expected; /* Capture-IR expected value */
|
||||
u8 *expected_mask; /* Capture-IR expected mask */
|
||||
u32 idcode; /* device identification code */
|
||||
u8 *cur_instr; /* current instruction */
|
||||
int bypass; /* bypass register selected */
|
||||
struct jtag_device_s *next;
|
||||
} jtag_device_t;
|
||||
|
||||
extern jtag_device_t *jtag_devices;
|
||||
extern int jtag_num_devices;
|
||||
extern int jtag_ir_scan_size;
|
||||
|
||||
enum reset_line_mode
|
||||
{
|
||||
LINE_OPEN_DRAIN = 0x0,
|
||||
LINE_PUSH_PULL = 0x1,
|
||||
};
|
||||
|
||||
typedef struct jtag_interface_s
|
||||
{
|
||||
char* name;
|
||||
|
||||
/* queued command execution
|
||||
*/
|
||||
int (*execute_queue)(void);
|
||||
|
||||
/* interface initalization
|
||||
*/
|
||||
int (*speed)(int speed);
|
||||
int (*register_commands)(struct command_context_s *cmd_ctx);
|
||||
int (*init)(void);
|
||||
int (*quit)(void);
|
||||
|
||||
} jtag_interface_t;
|
||||
|
||||
enum jtag_event
|
||||
{
|
||||
JTAG_SRST_ASSERTED,
|
||||
JTAG_TRST_ASSERTED,
|
||||
JTAG_SRST_RELEASED,
|
||||
JTAG_TRST_RELEASED,
|
||||
};
|
||||
|
||||
extern char* jtag_event_strings[];
|
||||
|
||||
extern int jtag_trst;
|
||||
extern int jtag_srst;
|
||||
|
||||
typedef struct jtag_event_callback_s
|
||||
{
|
||||
int (*callback)(enum jtag_event event, void *priv);
|
||||
void *priv;
|
||||
struct jtag_event_callback_s *next;
|
||||
} jtag_event_callback_t;
|
||||
|
||||
extern jtag_event_callback_t *jtag_event_callbacks;
|
||||
|
||||
extern jtag_interface_t *jtag; /* global pointer to configured JTAG interface */
|
||||
extern enum tap_state end_state;
|
||||
extern enum tap_state cur_state;
|
||||
|
||||
extern char* jtag_interface;
|
||||
extern int jtag_speed;
|
||||
|
||||
enum reset_types
|
||||
{
|
||||
RESET_NONE = 0x0,
|
||||
RESET_HAS_TRST = 0x1,
|
||||
RESET_HAS_SRST = 0x2,
|
||||
RESET_TRST_AND_SRST = 0x3,
|
||||
RESET_SRST_PULLS_TRST = 0x4,
|
||||
RESET_TRST_PULLS_SRST = 0x8,
|
||||
RESET_TRST_OPEN_DRAIN = 0x10,
|
||||
RESET_SRST_PUSH_PULL = 0x20,
|
||||
};
|
||||
|
||||
extern enum reset_types jtag_reset_config;
|
||||
|
||||
/* JTAG subsystem */
|
||||
extern int jtag_init(struct command_context_s *cmd_ctx);
|
||||
extern int jtag_register_commands(struct command_context_s *cmd_ctx);
|
||||
|
||||
/* JTAG interface, can be implemented with a software or hardware fifo */
|
||||
extern int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
|
||||
extern int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
|
||||
extern int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
|
||||
extern int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
|
||||
/* execute a state transition within the JTAG standard, but the exact path
|
||||
* path that is taken is undefined. Many implementations use precisely
|
||||
* 7 clocks to perform a transition, but it could be more or less
|
||||
* than that.
|
||||
*
|
||||
* The following assertions are made about certain common state moves:
|
||||
*
|
||||
* - A state move from Pause-[ID]R to Pause-[ID]R should always go through
|
||||
* Update-[ID]R and Capture-[ID]R before returning to Pause-[ID]R, otherwise
|
||||
* there's no way force a register update, if you can't go to Run-Test/Idle for
|
||||
* some reason.
|
||||
*
|
||||
* - A state move from Pause-[ID]R to Shift-[ID]R must not go through
|
||||
* Update-[ID]R.
|
||||
*
|
||||
* - Run-Test/Idle must not be entered unless requested, because R-T/I may have
|
||||
* side effects.
|
||||
*/
|
||||
extern int jtag_add_statemove(enum tap_state endstate);
|
||||
/* A list of unambigious single clock state transitions, not
|
||||
* all drivers can support this, but it is required for e.g.
|
||||
* XScale and Xilinx support
|
||||
*/
|
||||
extern int jtag_add_pathmove(int num_states, enum tap_state *path);
|
||||
/* cycle precisely num_cycles in the TAP_RTI state */
|
||||
extern int jtag_add_runtest(int num_cycles, enum tap_state endstate);
|
||||
extern int jtag_add_reset(int trst, int srst);
|
||||
extern int jtag_add_end_state(enum tap_state endstate);
|
||||
extern int jtag_add_sleep(u32 us);
|
||||
/*
|
||||
* For software FIFO implementations, the queued commands can be executed
|
||||
* during this call or earlier. A sw queue might decide to push out
|
||||
* some of the jtag_add_xxx() operations once the queue is "big enough".
|
||||
*
|
||||
* This fn will return an error code if any of the prior jtag_add_xxx()
|
||||
* calls caused a failure, e.g. check failure. Note that it does not
|
||||
* matter if the operation was executed *before* jtag_execute_queue(),
|
||||
* jtag_execute_queue() will still return an error code.
|
||||
*
|
||||
* All jtag_add_xxx() calls that have in_handler!=NULL will have been
|
||||
* executed when this fn returns, but if what has been queued only
|
||||
* clocks data out, without reading anything back, then JTAG could
|
||||
* be running *after* jtag_execute_queue() returns. The API does
|
||||
* not define a way to flush a hw FIFO that runs *after*
|
||||
* jtag_execute_queue() returns.
|
||||
*
|
||||
* jtag_add_xxx() commands can either be executed immediately or
|
||||
* at some time between the jtag_add_xxx() fn call and jtag_execute_queue().
|
||||
*/
|
||||
extern int jtag_execute_queue(void);
|
||||
|
||||
/* JTAG support functions */
|
||||
extern void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler);
|
||||
extern enum scan_type jtag_scan_type(scan_command_t *cmd);
|
||||
extern int jtag_scan_size(scan_command_t *cmd);
|
||||
extern int jtag_read_buffer(u8 *buffer, scan_command_t *cmd);
|
||||
extern int jtag_build_buffer(scan_command_t *cmd, u8 **buffer);
|
||||
extern jtag_device_t* jtag_get_device(int num);
|
||||
extern void jtag_sleep(u32 us);
|
||||
extern int jtag_call_event_callbacks(enum jtag_event event);
|
||||
extern int jtag_register_event_callback(int (*callback)(enum jtag_event event, void *priv), void *priv);
|
||||
|
||||
extern int jtag_verify_capture_ir;
|
||||
|
||||
|
||||
/* error codes
|
||||
* JTAG subsystem uses codes between -100 and -199 */
|
||||
|
||||
#define ERROR_JTAG_INIT_FAILED (-100)
|
||||
#define ERROR_JTAG_INVALID_INTERFACE (-101)
|
||||
#define ERROR_JTAG_NOT_IMPLEMENTED (-102)
|
||||
#define ERROR_JTAG_TRST_ASSERTED (-103)
|
||||
#define ERROR_JTAG_QUEUE_FAILED (-104)
|
||||
#define ERROR_JTAG_RESET_WOULD_ASSERT_TRST (-105)
|
||||
#define ERROR_JTAG_RESET_CANT_SRST (-106)
|
||||
#define ERROR_JTAG_DEVICE_ERROR (-107)
|
||||
#endif /* JTAG_H */
|
||||
|
|
|
@ -1,264 +1,264 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "virtex2.h"
|
||||
|
||||
#include "pld.h"
|
||||
#include "xilinx_bit.h"
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
#include "jtag.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int virtex2_register_commands(struct command_context_s *cmd_ctx);
|
||||
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device);
|
||||
int virtex2_load(struct pld_device_s *pld_device, char *filename);
|
||||
|
||||
pld_driver_t virtex2_pld =
|
||||
{
|
||||
.name = "virtex2",
|
||||
.register_commands = virtex2_register_commands,
|
||||
.pld_device_command = virtex2_pld_device_command,
|
||||
.load = virtex2_load,
|
||||
};
|
||||
|
||||
int virtex2_set_instr(int chain_pos, u32 new_instr)
|
||||
{
|
||||
jtag_device_t *device = jtag_get_device(chain_pos);
|
||||
|
||||
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
||||
{
|
||||
scan_field_t field;
|
||||
|
||||
field.device = chain_pos;
|
||||
field.num_bits = device->ir_length;
|
||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
field.in_check_value = NULL;
|
||||
field.in_check_mask = NULL;
|
||||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
|
||||
jtag_add_ir_scan(1, &field, TAP_RTI, NULL);
|
||||
|
||||
free(field.out_value);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_send_32(struct pld_device_s *pld_device, int num_words, u32 *words)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||
scan_field_t scan_field;
|
||||
u8 *values;
|
||||
int i;
|
||||
|
||||
values = malloc(num_words * 4);
|
||||
|
||||
scan_field.device = virtex2_info->chain_pos;
|
||||
scan_field.num_bits = num_words * 32;
|
||||
scan_field.out_value = values;
|
||||
scan_field.out_mask = NULL;
|
||||
scan_field.in_value = NULL;
|
||||
scan_field.in_check_value = NULL;
|
||||
scan_field.in_check_mask = NULL;
|
||||
scan_field.in_handler = NULL;
|
||||
scan_field.in_handler_priv = NULL;
|
||||
|
||||
for (i = 0; i < num_words; i++)
|
||||
buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
|
||||
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
||||
|
||||
jtag_add_dr_scan(1, &scan_field, TAP_PD, NULL);
|
||||
|
||||
free(values);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u32 *dest = priv;
|
||||
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_receive_32(struct pld_device_s *pld_device, int num_words, u32 *words)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||
scan_field_t scan_field;
|
||||
|
||||
scan_field.device = virtex2_info->chain_pos;
|
||||
scan_field.num_bits = 32;
|
||||
scan_field.out_value = NULL;
|
||||
scan_field.out_mask = NULL;
|
||||
scan_field.in_value = NULL;
|
||||
scan_field.in_check_value = NULL;
|
||||
scan_field.in_check_mask = NULL;
|
||||
scan_field.in_handler = virtex2_jtag_buf_to_u32;
|
||||
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x4); /* CFG_OUT */
|
||||
|
||||
while (num_words--)
|
||||
{
|
||||
scan_field.in_handler_priv = words++;
|
||||
jtag_add_dr_scan(1, &scan_field, TAP_PD, NULL);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_read_stat(struct pld_device_s *pld_device, u32 *status)
|
||||
{
|
||||
u32 data[5];
|
||||
|
||||
jtag_add_statemove(TAP_TLR);
|
||||
|
||||
data[0] = 0xaa995566; /* synch word */
|
||||
data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
|
||||
data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
|
||||
data[3] = 0x20000000; /* NOOP */
|
||||
data[4] = 0x20000000; /* NOOP */
|
||||
virtex2_send_32(pld_device, 5, data);
|
||||
|
||||
virtex2_receive_32(pld_device, 1, status);
|
||||
|
||||
jtag_execute_queue();
|
||||
|
||||
DEBUG("status: 0x%8.8x", *status);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_load(struct pld_device_s *pld_device, char *filename)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||
xilinx_bit_file_t bit_file;
|
||||
int retval;
|
||||
int i;
|
||||
|
||||
scan_field_t field;
|
||||
|
||||
field.device = virtex2_info->chain_pos;
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
field.in_check_value = NULL;
|
||||
field.in_check_mask = NULL;
|
||||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
|
||||
if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0xb); /* JPROG_B */
|
||||
jtag_execute_queue();
|
||||
jtag_add_sleep(1000);
|
||||
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
||||
jtag_execute_queue();
|
||||
|
||||
for (i = 0; i < bit_file.length; i++)
|
||||
bit_file.data[i] = flip_u32(bit_file.data[i], 8);
|
||||
|
||||
field.num_bits = bit_file.length * 8;
|
||||
field.out_value = bit_file.data;
|
||||
|
||||
jtag_add_dr_scan(1, &field, TAP_PD, NULL);
|
||||
jtag_execute_queue();
|
||||
|
||||
jtag_add_statemove(TAP_TLR);
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
||||
jtag_add_runtest(13, TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
||||
jtag_add_runtest(13, TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||
jtag_execute_queue();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_handle_read_stat_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
{
|
||||
pld_device_t *device;
|
||||
virtex2_pld_device_t *virtex2_info;
|
||||
u32 status;
|
||||
|
||||
if (argc < 1)
|
||||
{
|
||||
command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
device = get_pld_device_by_num(strtoul(args[0], NULL, 0));
|
||||
if (!device)
|
||||
{
|
||||
command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
virtex2_info = device->driver_priv;
|
||||
|
||||
virtex2_read_stat(device, &status);
|
||||
|
||||
command_print(cmd_ctx, "virtex2 status register: 0x%8.8x", status);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
command_t *virtex2_cmd = register_command(cmd_ctx, NULL, "virtex2", NULL, COMMAND_ANY, "virtex2 specific commands");
|
||||
|
||||
register_command(cmd_ctx, virtex2_cmd, "read_stat", virtex2_handle_read_stat_command, COMMAND_EXEC,
|
||||
"read Virtex-II status register");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
WARNING("incomplete pld device 'virtex2' configuration");
|
||||
return ERROR_PLD_DEVICE_INVALID;
|
||||
}
|
||||
|
||||
virtex2_info = malloc(sizeof(virtex2_pld_device_t));
|
||||
pld_device->driver_priv = virtex2_info;
|
||||
|
||||
virtex2_info->chain_pos = strtoul(args[1], NULL, 0);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "virtex2.h"
|
||||
|
||||
#include "pld.h"
|
||||
#include "xilinx_bit.h"
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
#include "jtag.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int virtex2_register_commands(struct command_context_s *cmd_ctx);
|
||||
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device);
|
||||
int virtex2_load(struct pld_device_s *pld_device, char *filename);
|
||||
|
||||
pld_driver_t virtex2_pld =
|
||||
{
|
||||
.name = "virtex2",
|
||||
.register_commands = virtex2_register_commands,
|
||||
.pld_device_command = virtex2_pld_device_command,
|
||||
.load = virtex2_load,
|
||||
};
|
||||
|
||||
int virtex2_set_instr(int chain_pos, u32 new_instr)
|
||||
{
|
||||
jtag_device_t *device = jtag_get_device(chain_pos);
|
||||
|
||||
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
||||
{
|
||||
scan_field_t field;
|
||||
|
||||
field.device = chain_pos;
|
||||
field.num_bits = device->ir_length;
|
||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
field.in_check_value = NULL;
|
||||
field.in_check_mask = NULL;
|
||||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
|
||||
jtag_add_ir_scan(1, &field, TAP_RTI);
|
||||
|
||||
free(field.out_value);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_send_32(struct pld_device_s *pld_device, int num_words, u32 *words)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||
scan_field_t scan_field;
|
||||
u8 *values;
|
||||
int i;
|
||||
|
||||
values = malloc(num_words * 4);
|
||||
|
||||
scan_field.device = virtex2_info->chain_pos;
|
||||
scan_field.num_bits = num_words * 32;
|
||||
scan_field.out_value = values;
|
||||
scan_field.out_mask = NULL;
|
||||
scan_field.in_value = NULL;
|
||||
scan_field.in_check_value = NULL;
|
||||
scan_field.in_check_mask = NULL;
|
||||
scan_field.in_handler = NULL;
|
||||
scan_field.in_handler_priv = NULL;
|
||||
|
||||
for (i = 0; i < num_words; i++)
|
||||
buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
|
||||
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
||||
|
||||
jtag_add_dr_scan(1, &scan_field, TAP_PD);
|
||||
|
||||
free(values);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u32 *dest = priv;
|
||||
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_receive_32(struct pld_device_s *pld_device, int num_words, u32 *words)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||
scan_field_t scan_field;
|
||||
|
||||
scan_field.device = virtex2_info->chain_pos;
|
||||
scan_field.num_bits = 32;
|
||||
scan_field.out_value = NULL;
|
||||
scan_field.out_mask = NULL;
|
||||
scan_field.in_value = NULL;
|
||||
scan_field.in_check_value = NULL;
|
||||
scan_field.in_check_mask = NULL;
|
||||
scan_field.in_handler = virtex2_jtag_buf_to_u32;
|
||||
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x4); /* CFG_OUT */
|
||||
|
||||
while (num_words--)
|
||||
{
|
||||
scan_field.in_handler_priv = words++;
|
||||
jtag_add_dr_scan(1, &scan_field, TAP_PD);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_read_stat(struct pld_device_s *pld_device, u32 *status)
|
||||
{
|
||||
u32 data[5];
|
||||
|
||||
jtag_add_statemove(TAP_TLR);
|
||||
|
||||
data[0] = 0xaa995566; /* synch word */
|
||||
data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
|
||||
data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
|
||||
data[3] = 0x20000000; /* NOOP */
|
||||
data[4] = 0x20000000; /* NOOP */
|
||||
virtex2_send_32(pld_device, 5, data);
|
||||
|
||||
virtex2_receive_32(pld_device, 1, status);
|
||||
|
||||
jtag_execute_queue();
|
||||
|
||||
DEBUG("status: 0x%8.8x", *status);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_load(struct pld_device_s *pld_device, char *filename)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||
xilinx_bit_file_t bit_file;
|
||||
int retval;
|
||||
int i;
|
||||
|
||||
scan_field_t field;
|
||||
|
||||
field.device = virtex2_info->chain_pos;
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
field.in_check_value = NULL;
|
||||
field.in_check_mask = NULL;
|
||||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
|
||||
if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0xb); /* JPROG_B */
|
||||
jtag_execute_queue();
|
||||
jtag_add_sleep(1000);
|
||||
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
||||
jtag_execute_queue();
|
||||
|
||||
for (i = 0; i < bit_file.length; i++)
|
||||
bit_file.data[i] = flip_u32(bit_file.data[i], 8);
|
||||
|
||||
field.num_bits = bit_file.length * 8;
|
||||
field.out_value = bit_file.data;
|
||||
|
||||
jtag_add_dr_scan(1, &field, TAP_PD);
|
||||
jtag_execute_queue();
|
||||
|
||||
jtag_add_statemove(TAP_TLR);
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
||||
jtag_add_runtest(13, TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
||||
jtag_add_runtest(13, TAP_RTI);
|
||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||
jtag_execute_queue();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_handle_read_stat_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
{
|
||||
pld_device_t *device;
|
||||
virtex2_pld_device_t *virtex2_info;
|
||||
u32 status;
|
||||
|
||||
if (argc < 1)
|
||||
{
|
||||
command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
device = get_pld_device_by_num(strtoul(args[0], NULL, 0));
|
||||
if (!device)
|
||||
{
|
||||
command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
virtex2_info = device->driver_priv;
|
||||
|
||||
virtex2_read_stat(device, &status);
|
||||
|
||||
command_print(cmd_ctx, "virtex2 status register: 0x%8.8x", status);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
command_t *virtex2_cmd = register_command(cmd_ctx, NULL, "virtex2", NULL, COMMAND_ANY, "virtex2 specific commands");
|
||||
|
||||
register_command(cmd_ctx, virtex2_cmd, "read_stat", virtex2_handle_read_stat_command, COMMAND_EXEC,
|
||||
"read Virtex-II status register");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device)
|
||||
{
|
||||
virtex2_pld_device_t *virtex2_info;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
WARNING("incomplete pld device 'virtex2' configuration");
|
||||
return ERROR_PLD_DEVICE_INVALID;
|
||||
}
|
||||
|
||||
virtex2_info = malloc(sizeof(virtex2_pld_device_t));
|
||||
pld_device->driver_priv = virtex2_info;
|
||||
|
||||
virtex2_info->chain_pos = strtoul(args[1], NULL, 0);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,250 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 digenius technology GmbH. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ARM11_H
|
||||
#define ARM11_H
|
||||
|
||||
#include "target.h"
|
||||
#include "register.h"
|
||||
#include "embeddedice.h"
|
||||
#include "arm_jtag.h"
|
||||
|
||||
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define asizeof(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#define NEW(type, variable, items) \
|
||||
type * variable = malloc(sizeof(type) * items)
|
||||
|
||||
|
||||
#define ARM11_REGCACHE_MODEREGS 0
|
||||
#define ARM11_REGCACHE_FREGS 0
|
||||
|
||||
#define ARM11_REGCACHE_COUNT (20 + \
|
||||
23 * ARM11_REGCACHE_MODEREGS + \
|
||||
9 * ARM11_REGCACHE_FREGS)
|
||||
|
||||
|
||||
typedef struct arm11_register_history_s
|
||||
{
|
||||
u32 value;
|
||||
u8 valid;
|
||||
}arm11_register_history_t;
|
||||
|
||||
|
||||
|
||||
typedef struct arm11_common_s
|
||||
{
|
||||
target_t * target;
|
||||
|
||||
arm_jtag_t jtag_info;
|
||||
|
||||
/** \name Processor type detection */
|
||||
/*@{*/
|
||||
|
||||
u32 device_id; /**< IDCODE readout */
|
||||
u32 didr; /**< DIDR readout (debug capabilities) */
|
||||
u8 implementor; /**< DIDR Implementor readout */
|
||||
|
||||
size_t brp; /**< Number of Breakpoint Register Pairs */
|
||||
size_t wrp; /**< Number of Watchpoint Register Pairs */
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
u32 last_dscr; /**< Last retrieved DSCR value;
|
||||
* Can be used to detect changes */
|
||||
|
||||
u8 trst_active;
|
||||
u8 halt_requested;
|
||||
|
||||
/** \name Shadow registers to save processor state */
|
||||
/*@{*/
|
||||
|
||||
reg_t * reg_list; /**< target register list */
|
||||
u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */
|
||||
|
||||
/*@}*/
|
||||
|
||||
arm11_register_history_t
|
||||
reg_history[ARM11_REGCACHE_COUNT]; /**< register state before last resume */
|
||||
|
||||
|
||||
} arm11_common_t;
|
||||
|
||||
|
||||
/**
|
||||
* ARM11 DBGTAP instructions
|
||||
*
|
||||
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html
|
||||
*/
|
||||
enum arm11_instructions
|
||||
{
|
||||
ARM11_EXTEST = 0x00,
|
||||
ARM11_SCAN_N = 0x02,
|
||||
ARM11_RESTART = 0x04,
|
||||
ARM11_HALT = 0x08,
|
||||
ARM11_INTEST = 0x0C,
|
||||
ARM11_ITRSEL = 0x1D,
|
||||
ARM11_IDCODE = 0x1E,
|
||||
ARM11_BYPASS = 0x1F,
|
||||
};
|
||||
|
||||
enum arm11_dscr
|
||||
{
|
||||
ARM11_DSCR_CORE_HALTED = 1 << 0,
|
||||
ARM11_DSCR_CORE_RESTARTED = 1 << 1,
|
||||
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2,
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2,
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2,
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2,
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
|
||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
|
||||
|
||||
ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6,
|
||||
ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7,
|
||||
ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13,
|
||||
ARM11_DSCR_MODE_SELECT = 1 << 14,
|
||||
ARM11_DSCR_WDTR_FULL = 1 << 29,
|
||||
ARM11_DSCR_RDTR_FULL = 1 << 30,
|
||||
};
|
||||
|
||||
enum arm11_cpsr
|
||||
{
|
||||
ARM11_CPSR_T = 1 << 5,
|
||||
ARM11_CPSR_J = 1 << 24,
|
||||
};
|
||||
|
||||
enum arm11_sc7
|
||||
{
|
||||
ARM11_SC7_NULL = 0,
|
||||
ARM11_SC7_VCR = 7,
|
||||
ARM11_SC7_PC = 8,
|
||||
ARM11_SC7_BVR0 = 64,
|
||||
ARM11_SC7_BCR0 = 80,
|
||||
ARM11_SC7_WVR0 = 96,
|
||||
ARM11_SC7_WCR0 = 112,
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct arm11_reg_state_s
|
||||
{
|
||||
u32 def_index;
|
||||
target_t * target;
|
||||
} arm11_reg_state_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/* poll current target status */
|
||||
int arm11_poll(struct target_s *target);
|
||||
/* architecture specific status reply */
|
||||
int arm11_arch_state(struct target_s *target);
|
||||
|
||||
/* target request support */
|
||||
int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer);
|
||||
|
||||
/* target execution control */
|
||||
int arm11_halt(struct target_s *target);
|
||||
int arm11_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
|
||||
int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
|
||||
|
||||
/* target reset control */
|
||||
int arm11_assert_reset(struct target_s *target);
|
||||
int arm11_deassert_reset(struct target_s *target);
|
||||
int arm11_soft_reset_halt(struct target_s *target);
|
||||
int arm11_prepare_reset_halt(struct target_s *target);
|
||||
|
||||
/* target register access for gdb */
|
||||
int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
|
||||
|
||||
/* target memory access
|
||||
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
|
||||
* count: number of items of <size>
|
||||
*/
|
||||
int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
|
||||
int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
|
||||
|
||||
/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
|
||||
int arm11_bulk_write_memory(struct target_s *target, u32 address, u32 count, u8 *buffer);
|
||||
|
||||
int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
|
||||
|
||||
/* target break-/watchpoint control
|
||||
* rw: 0 = write, 1 = read, 2 = access
|
||||
*/
|
||||
int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
|
||||
int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
|
||||
int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
|
||||
int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
|
||||
|
||||
/* target algorithm support */
|
||||
int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info);
|
||||
|
||||
int arm11_register_commands(struct command_context_s *cmd_ctx);
|
||||
int arm11_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
|
||||
int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
|
||||
int arm11_quit(void);
|
||||
|
||||
|
||||
/* helpers */
|
||||
void arm11_build_reg_cache(target_t *target);
|
||||
|
||||
|
||||
/* internals */
|
||||
|
||||
void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field);
|
||||
void arm11_add_IR (arm11_common_t * arm11, u8 instr, enum tap_state state);
|
||||
void arm11_add_debug_SCAN_N (arm11_common_t * arm11, u8 chain, enum tap_state state);
|
||||
void arm11_add_debug_INST (arm11_common_t * arm11, u32 inst, u8 * flag, enum tap_state state);
|
||||
u32 arm11_read_DSCR (arm11_common_t * arm11);
|
||||
void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr);
|
||||
|
||||
enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr);
|
||||
|
||||
void arm11_run_instr_data_prepare (arm11_common_t * arm11);
|
||||
void arm11_run_instr_data_finish (arm11_common_t * arm11);
|
||||
void arm11_run_instr_no_data (arm11_common_t * arm11, u32 * opcode, size_t count);
|
||||
void arm11_run_instr_no_data1 (arm11_common_t * arm11, u32 opcode);
|
||||
void arm11_run_instr_data_to_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
|
||||
void arm11_run_instr_data_to_core1 (arm11_common_t * arm11, u32 opcode, u32 data);
|
||||
void arm11_run_instr_data_from_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
|
||||
void arm11_run_instr_data_from_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 * data);
|
||||
void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 data);
|
||||
|
||||
|
||||
typedef struct arm11_sc7_action_s
|
||||
{
|
||||
bool write;
|
||||
u8 address;
|
||||
u32 value;
|
||||
} arm11_sc7_action_t;
|
||||
|
||||
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count);
|
||||
void arm11_sc7_clear_bw(arm11_common_t * arm11);
|
||||
|
||||
|
||||
|
||||
#endif /* ARM11_H */
|
|
@ -0,0 +1,611 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 digenius technology GmbH. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arm11.h"
|
||||
#include "jtag.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if 0
|
||||
#define JTAG_DEBUG(expr ...) \
|
||||
do { \
|
||||
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||
} while(0)
|
||||
#else
|
||||
#define JTAG_DEBUG(expr ...) \
|
||||
do {} while(0)
|
||||
#endif
|
||||
|
||||
/** Code de-clutter: Construct scan_field_t to write out a value
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param num_bits Length of the data field
|
||||
* \param out_data pointer to the data that will be sent out
|
||||
* <em>(data is read when it is added to the JTAG queue)</em>
|
||||
* \param in_data pointer to the memory that will receive data that was clocked in
|
||||
* <em>(data is written when the JTAG queue is executed)</em>
|
||||
* \param field target data structure that will be initialized
|
||||
*/
|
||||
void arm11_setup_field(arm11_common_t * arm11, int num_bits, void * out_data, void * in_data, scan_field_t * field)
|
||||
{
|
||||
field->device = arm11->jtag_info.chain_pos;
|
||||
field->num_bits = num_bits;
|
||||
field->out_mask = NULL;
|
||||
field->in_check_mask = NULL;
|
||||
field->in_check_value = NULL;
|
||||
field->in_handler = NULL;
|
||||
field->in_handler_priv = NULL;
|
||||
|
||||
field->out_value = out_data;
|
||||
field->in_value = in_data;
|
||||
}
|
||||
|
||||
|
||||
/** Write JTAG instruction register
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param instr An ARM11 DBGTAP instruction. Use enum #arm11_instructions.
|
||||
* \param state Pass the final TAP state or -1 for the default value (Pause-IR).
|
||||
*
|
||||
* \remarks This adds to the JTAG command queue but does \em not execute it.
|
||||
*/
|
||||
void arm11_add_IR(arm11_common_t * arm11, u8 instr, enum tap_state state)
|
||||
{
|
||||
jtag_device_t *device = jtag_get_device(arm11->jtag_info.chain_pos);
|
||||
|
||||
if (buf_get_u32(device->cur_instr, 0, 5) == instr)
|
||||
{
|
||||
JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr);
|
||||
return;
|
||||
}
|
||||
|
||||
JTAG_DEBUG("IR <= 0x%02x", instr);
|
||||
|
||||
scan_field_t field;
|
||||
|
||||
arm11_setup_field(arm11, 5, &instr, NULL, &field);
|
||||
|
||||
jtag_add_ir_scan_vc(1, &field, state == -1 ? TAP_PI : state);
|
||||
}
|
||||
|
||||
/** Verify shifted out data from Scan Chain Register (SCREG)
|
||||
* Used as parameter to scan_field_t::in_handler in
|
||||
* arm11_add_debug_SCAN_N().
|
||||
*
|
||||
*/
|
||||
static int arm11_in_handler_SCAN_N(u8 *in_value, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
/** \todo TODO: clarify why this isnt properly masked in jtag.c jtag_read_buffer() */
|
||||
u8 v = *in_value & 0x1F;
|
||||
|
||||
if (v != 0x10)
|
||||
{
|
||||
ERROR("'arm11 target' JTAG communication error SCREG SCAN OUT 0x%02x (expected 0x10)", v);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
JTAG_DEBUG("SCREG SCAN OUT 0x%02x", v);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** Select and write to Scan Chain Register (SCREG)
|
||||
*
|
||||
* This function sets the instruction register to SCAN_N and writes
|
||||
* the data register with the selected chain number.
|
||||
*
|
||||
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/Cacbjhfg.html
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param chain Scan chain that will be selected.
|
||||
* \param state Pass the final TAP state or -1 for the default
|
||||
* value (Pause-DR).
|
||||
*
|
||||
* The chain takes effect when Update-DR is passed (usually when subsequently
|
||||
* the INTEXT/EXTEST instructions are written).
|
||||
*
|
||||
* \warning (Obsolete) Using this twice in a row will \em fail. The first call will end
|
||||
* in Pause-DR. The second call, due to the IR caching, will not
|
||||
* go through Capture-DR when shifting in the new scan chain number.
|
||||
* As a result the verification in arm11_in_handler_SCAN_N() must
|
||||
* fail.
|
||||
*
|
||||
* \remarks This adds to the JTAG command queue but does \em not execute it.
|
||||
*/
|
||||
|
||||
void arm11_add_debug_SCAN_N(arm11_common_t * arm11, u8 chain, enum tap_state state)
|
||||
{
|
||||
JTAG_DEBUG("SCREG <= 0x%02x", chain);
|
||||
|
||||
arm11_add_IR(arm11, ARM11_SCAN_N, -1);
|
||||
|
||||
scan_field_t field;
|
||||
|
||||
arm11_setup_field(arm11, 5, &chain, NULL, &field);
|
||||
|
||||
field.in_handler = arm11_in_handler_SCAN_N;
|
||||
|
||||
jtag_add_dr_scan_vc(1, &field, state == -1 ? TAP_PD : state);
|
||||
}
|
||||
|
||||
/** Write an instruction into the ITR register
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param inst An ARM11 processor instruction/opcode.
|
||||
* \param flag Optional parameter to retrieve the InstCompl flag
|
||||
* (this will be written when the JTAG chain is executed).
|
||||
* \param state Pass the final TAP state or -1 for the default
|
||||
* value (Run-Test/Idle).
|
||||
*
|
||||
* \remarks By default this ends with Run-Test/Idle state
|
||||
* and causes the instruction to be executed. If
|
||||
* a subsequent write to DTR is needed before
|
||||
* executing the instruction then TAP_PD should be
|
||||
* passed to \p state.
|
||||
*
|
||||
* \remarks This adds to the JTAG command queue but does \em not execute it.
|
||||
*/
|
||||
void arm11_add_debug_INST(arm11_common_t * arm11, u32 inst, u8 * flag, enum tap_state state)
|
||||
{
|
||||
JTAG_DEBUG("INST <= 0x%08x", inst);
|
||||
|
||||
scan_field_t itr[2];
|
||||
|
||||
arm11_setup_field(arm11, 32, &inst, NULL, itr + 0);
|
||||
arm11_setup_field(arm11, 1, NULL, flag, itr + 1);
|
||||
|
||||
jtag_add_dr_scan_vc(asizeof(itr), itr, state == -1 ? TAP_RTI : state);
|
||||
}
|
||||
|
||||
/** Read the Debug Status and Control Register (DSCR)
|
||||
*
|
||||
* same as CP14 c1
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \return DSCR content
|
||||
*
|
||||
* \remarks This is a stand-alone function that executes the JTAG command queue.
|
||||
*/
|
||||
u32 arm11_read_DSCR(arm11_common_t * arm11)
|
||||
{
|
||||
arm11_add_debug_SCAN_N(arm11, 0x01, -1);
|
||||
|
||||
arm11_add_IR(arm11, ARM11_INTEST, -1);
|
||||
|
||||
u32 dscr;
|
||||
scan_field_t chain1_field;
|
||||
|
||||
arm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field);
|
||||
|
||||
jtag_add_dr_scan_vc(1, &chain1_field, TAP_PD);
|
||||
|
||||
jtag_execute_queue();
|
||||
|
||||
if (arm11->last_dscr != dscr)
|
||||
JTAG_DEBUG("DSCR = %08x (OLD %08x)", dscr, arm11->last_dscr);
|
||||
|
||||
arm11->last_dscr = dscr;
|
||||
|
||||
return dscr;
|
||||
}
|
||||
|
||||
/** Write the Debug Status and Control Register (DSCR)
|
||||
*
|
||||
* same as CP14 c1
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param dscr DSCR content
|
||||
*
|
||||
* \remarks This is a stand-alone function that executes the JTAG command queue.
|
||||
*/
|
||||
void arm11_write_DSCR(arm11_common_t * arm11, u32 dscr)
|
||||
{
|
||||
arm11_add_debug_SCAN_N(arm11, 0x01, -1);
|
||||
|
||||
arm11_add_IR(arm11, ARM11_EXTEST, -1);
|
||||
|
||||
scan_field_t chain1_field;
|
||||
|
||||
arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field);
|
||||
|
||||
jtag_add_dr_scan_vc(1, &chain1_field, TAP_PD);
|
||||
|
||||
jtag_execute_queue();
|
||||
|
||||
JTAG_DEBUG("DSCR <= %08x (OLD %08x)", dscr, arm11->last_dscr);
|
||||
|
||||
arm11->last_dscr = dscr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Get the debug reason from Debug Status and Control Register (DSCR)
|
||||
*
|
||||
* \param dscr DSCR value to analyze
|
||||
* \return Debug reason
|
||||
*
|
||||
*/
|
||||
enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr)
|
||||
{
|
||||
switch (dscr & ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK)
|
||||
{
|
||||
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT: return DBG_REASON_DBGRQ;
|
||||
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT: return DBG_REASON_BREAKPOINT;
|
||||
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT: return DBG_REASON_WATCHPOINT;
|
||||
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION: return DBG_REASON_BREAKPOINT;
|
||||
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ: return DBG_REASON_DBGRQ;
|
||||
case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH: return DBG_REASON_BREAKPOINT;
|
||||
|
||||
default:
|
||||
return DBG_REASON_DBGRQ;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Prepare the stage for ITR/DTR operations
|
||||
* from the arm11_run_instr... group of functions.
|
||||
*
|
||||
* Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
|
||||
* around a block of arm11_run_instr_... calls.
|
||||
*
|
||||
* Select scan chain 5 to allow quick access to DTR. When scan
|
||||
* chain 4 is needed to put in a register the ITRSel instruction
|
||||
* shortcut is used instead of actually changing the Scan_N
|
||||
* register.
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_prepare(arm11_common_t * arm11)
|
||||
{
|
||||
arm11_add_debug_SCAN_N(arm11, 0x05, -1);
|
||||
}
|
||||
|
||||
/** Cleanup after ITR/DTR operations
|
||||
* from the arm11_run_instr... group of functions
|
||||
*
|
||||
* Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
|
||||
* around a block of arm11_run_instr_... calls.
|
||||
*
|
||||
* Any RTI can lead to an instruction execution when
|
||||
* scan chains 4 or 5 are selected and the IR holds
|
||||
* INTEST or EXTEST. So we must disable that before
|
||||
* any following activities lead to an RTI.
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_finish(arm11_common_t * arm11)
|
||||
{
|
||||
arm11_add_debug_SCAN_N(arm11, 0x00, -1);
|
||||
}
|
||||
|
||||
|
||||
/** Execute one or multiple instructions via ITR
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode Pointer to sequence of ARM opcodes
|
||||
* \param count Number of opcodes to execute
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_no_data(arm11_common_t * arm11, u32 * opcode, size_t count)
|
||||
{
|
||||
arm11_add_IR(arm11, ARM11_ITRSEL, -1);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_RTI);
|
||||
|
||||
while (1)
|
||||
{
|
||||
u8 flag;
|
||||
|
||||
arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_RTI : TAP_PD);
|
||||
|
||||
jtag_execute_queue();
|
||||
|
||||
if (flag)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Execute one instruction via ITR
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode ARM opcode
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_no_data1(arm11_common_t * arm11, u32 opcode)
|
||||
{
|
||||
arm11_run_instr_no_data(arm11, &opcode, 1);
|
||||
}
|
||||
|
||||
|
||||
/** Execute one instruction via ITR repeatedly while
|
||||
* passing data to the core via DTR on each execution.
|
||||
*
|
||||
* The executed instruction \em must read data from DTR.
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode ARM opcode
|
||||
* \param data Pointer to the data words to be passed to the core
|
||||
* \param count Number of data words and instruction repetitions
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_to_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
|
||||
{
|
||||
arm11_add_IR(arm11, ARM11_ITRSEL, -1);
|
||||
|
||||
arm11_add_debug_INST(arm11, opcode, NULL, TAP_PD);
|
||||
|
||||
arm11_add_IR(arm11, ARM11_EXTEST, -1);
|
||||
|
||||
scan_field_t chain5_fields[3];
|
||||
|
||||
u32 Data;
|
||||
u8 Ready;
|
||||
u8 nRetry;
|
||||
|
||||
arm11_setup_field(arm11, 32, &Data, NULL, chain5_fields + 0);
|
||||
arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1);
|
||||
arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
do
|
||||
{
|
||||
Data = *data;
|
||||
|
||||
jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_RTI);
|
||||
jtag_execute_queue();
|
||||
|
||||
JTAG_DEBUG("DTR Ready %d nRetry %d", Ready, nRetry);
|
||||
}
|
||||
while (!Ready);
|
||||
|
||||
data++;
|
||||
}
|
||||
|
||||
arm11_add_IR(arm11, ARM11_INTEST, -1);
|
||||
|
||||
do
|
||||
{
|
||||
Data = 0;
|
||||
|
||||
jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_PD);
|
||||
jtag_execute_queue();
|
||||
|
||||
JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry);
|
||||
}
|
||||
while (!Ready);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** Execute an instruction via ITR while handing data into the core via DTR.
|
||||
*
|
||||
* The executed instruction \em must read data from DTR.
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode ARM opcode
|
||||
* \param data Data word to be passed to the core via DTR
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_to_core1(arm11_common_t * arm11, u32 opcode, u32 data)
|
||||
{
|
||||
arm11_run_instr_data_to_core(arm11, opcode, &data, 1);
|
||||
}
|
||||
|
||||
|
||||
/** Execute one instruction via ITR repeatedly while
|
||||
* reading data from the core via DTR on each execution.
|
||||
*
|
||||
* The executed instruction \em must write data to DTR.
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode ARM opcode
|
||||
* \param data Pointer to an array that receives the data words from the core
|
||||
* \param count Number of data words and instruction repetitions
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
|
||||
{
|
||||
arm11_add_IR(arm11, ARM11_ITRSEL, -1);
|
||||
|
||||
arm11_add_debug_INST(arm11, opcode, NULL, TAP_RTI);
|
||||
|
||||
arm11_add_IR(arm11, ARM11_INTEST, -1);
|
||||
|
||||
scan_field_t chain5_fields[3];
|
||||
|
||||
u32 Data;
|
||||
u8 Ready;
|
||||
u8 nRetry;
|
||||
|
||||
arm11_setup_field(arm11, 32, NULL, &Data, chain5_fields + 0);
|
||||
arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1);
|
||||
arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
do
|
||||
{
|
||||
jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, count ? TAP_RTI : TAP_PD);
|
||||
jtag_execute_queue();
|
||||
|
||||
JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry);
|
||||
}
|
||||
while (!Ready);
|
||||
|
||||
*data++ = Data;
|
||||
}
|
||||
}
|
||||
|
||||
/** Execute one instruction via ITR
|
||||
* then load r0 into DTR and read DTR from core.
|
||||
*
|
||||
* The first executed instruction (\p opcode) should write data to r0.
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode ARM opcode to write r0 with the value of interest
|
||||
* \param data Pointer to a data word that receives the value from r0 after \p opcode was executed.
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_from_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 * data)
|
||||
{
|
||||
arm11_run_instr_no_data1(arm11, opcode);
|
||||
|
||||
/* MCR p14,0,R0,c0,c5,0 (move r0 -> wDTR -> local var) */
|
||||
arm11_run_instr_data_from_core(arm11, 0xEE000E15, data, 1);
|
||||
}
|
||||
|
||||
/** Load data into core via DTR then move it to r0 then
|
||||
* execute one instruction via ITR
|
||||
*
|
||||
* The final executed instruction (\p opcode) should read data from r0.
|
||||
*
|
||||
* \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block
|
||||
*
|
||||
* \param arm11 Target state variable.
|
||||
* \param opcode ARM opcode to read r0 act upon it
|
||||
* \param data Data word that will be written to r0 before \p opcode is executed
|
||||
*
|
||||
*/
|
||||
void arm11_run_instr_data_to_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 data)
|
||||
{
|
||||
/* MRC p14,0,r0,c0,c5,0 */
|
||||
arm11_run_instr_data_to_core1(arm11, 0xEE100E15, data);
|
||||
|
||||
arm11_run_instr_no_data1(arm11, opcode);
|
||||
}
|
||||
|
||||
|
||||
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count)
|
||||
{
|
||||
arm11_add_debug_SCAN_N(arm11, 0x07, -1);
|
||||
|
||||
arm11_add_IR(arm11, ARM11_EXTEST, -1);
|
||||
|
||||
scan_field_t chain7_fields[3];
|
||||
|
||||
u8 nRW;
|
||||
u32 DataOut;
|
||||
u8 AddressOut;
|
||||
u8 Ready;
|
||||
u32 DataIn;
|
||||
u8 AddressIn;
|
||||
|
||||
arm11_setup_field(arm11, 1, &nRW, &Ready, chain7_fields + 0);
|
||||
arm11_setup_field(arm11, 32, &DataOut, &DataIn, chain7_fields + 1);
|
||||
arm11_setup_field(arm11, 7, &AddressOut, &AddressIn, chain7_fields + 2);
|
||||
|
||||
{size_t i;
|
||||
for (i = 0; i < count + 1; i++)
|
||||
{
|
||||
if (i < count)
|
||||
{
|
||||
nRW = actions[i].write ? 1 : 0;
|
||||
DataOut = actions[i].value;
|
||||
AddressOut = actions[i].address;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRW = 0;
|
||||
DataOut = 0;
|
||||
AddressOut = 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
JTAG_DEBUG("SC7 <= Address %02x Data %08x nRW %d", AddressOut, DataOut, nRW);
|
||||
|
||||
jtag_add_dr_scan_vc(asizeof(chain7_fields), chain7_fields, TAP_PD);
|
||||
jtag_execute_queue();
|
||||
|
||||
JTAG_DEBUG("SC7 => Address %02x Data %08x Ready %d", AddressIn, DataIn, Ready);
|
||||
}
|
||||
while (!Ready); /* 'nRW' is 'Ready' on read out */
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
if (actions[i - 1].address != AddressIn)
|
||||
{
|
||||
WARNING("Scan chain 7 shifted out unexpected address");
|
||||
}
|
||||
|
||||
if (!actions[i - 1].write)
|
||||
{
|
||||
actions[i - 1].value = DataIn;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actions[i - 1].value != DataIn)
|
||||
{
|
||||
WARNING("Scan chain 7 shifted out unexpected data");
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
{size_t i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
JTAG_DEBUG("SC7 %02d: %02x %s %08x", i, actions[i].address, actions[i].write ? "<=" : "=>", actions[i].value);
|
||||
}}
|
||||
}
|
||||
|
||||
void arm11_sc7_clear_bw(arm11_common_t * arm11)
|
||||
{
|
||||
size_t actions = arm11->brp + arm11->wrp;
|
||||
|
||||
arm11_sc7_action_t clear_bw[actions];
|
||||
|
||||
{size_t i;
|
||||
for (i = 0; i < actions; i++)
|
||||
{
|
||||
clear_bw[i].write = true;
|
||||
clear_bw[i].value = 0;
|
||||
clear_bw[i].address =
|
||||
i < arm11->brp ?
|
||||
ARM11_SC7_BCR0 + i :
|
||||
ARM11_SC7_WCR0 + i - arm11->brp;
|
||||
}}
|
||||
|
||||
arm11_sc7_run(arm11, clear_bw, actions);
|
||||
}
|
||||
|
1252
src/target/arm720t.c
1252
src/target/arm720t.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2970
src/target/arm920t.c
2970
src/target/arm920t.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,364 +1,364 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arm966e.h"
|
||||
|
||||
#include "arm7_9_common.h"
|
||||
#include "register.h"
|
||||
#include "target.h"
|
||||
#include "armv4_5.h"
|
||||
#include "embeddedice.h"
|
||||
#include "log.h"
|
||||
#include "jtag.h"
|
||||
#include "arm_jtag.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if 0
|
||||
#define _DEBUG_INSTRUCTION_EXECUTION_
|
||||
#endif
|
||||
|
||||
/* cli handling */
|
||||
int arm966e_register_commands(struct command_context_s *cmd_ctx);
|
||||
|
||||
/* forward declarations */
|
||||
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
|
||||
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
|
||||
int arm966e_quit(void);
|
||||
|
||||
target_type_t arm966e_target =
|
||||
{
|
||||
.name = "arm966e",
|
||||
|
||||
.poll = arm7_9_poll,
|
||||
.arch_state = armv4_5_arch_state,
|
||||
|
||||
.target_request_data = arm7_9_target_request_data,
|
||||
|
||||
.halt = arm7_9_halt,
|
||||
.resume = arm7_9_resume,
|
||||
.step = arm7_9_step,
|
||||
|
||||
.assert_reset = arm7_9_assert_reset,
|
||||
.deassert_reset = arm7_9_deassert_reset,
|
||||
.soft_reset_halt = arm7_9_soft_reset_halt,
|
||||
.prepare_reset_halt = arm7_9_prepare_reset_halt,
|
||||
|
||||
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
|
||||
|
||||
.read_memory = arm7_9_read_memory,
|
||||
.write_memory = arm7_9_write_memory,
|
||||
.bulk_write_memory = arm7_9_bulk_write_memory,
|
||||
.checksum_memory = arm7_9_checksum_memory,
|
||||
|
||||
.run_algorithm = armv4_5_run_algorithm,
|
||||
|
||||
.add_breakpoint = arm7_9_add_breakpoint,
|
||||
.remove_breakpoint = arm7_9_remove_breakpoint,
|
||||
.add_watchpoint = arm7_9_add_watchpoint,
|
||||
.remove_watchpoint = arm7_9_remove_watchpoint,
|
||||
|
||||
.register_commands = arm966e_register_commands,
|
||||
.target_command = arm966e_target_command,
|
||||
.init_target = arm966e_init_target,
|
||||
.quit = arm966e_quit,
|
||||
};
|
||||
|
||||
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
|
||||
{
|
||||
arm9tdmi_init_target(cmd_ctx, target);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_quit(void)
|
||||
{
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
|
||||
{
|
||||
arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
|
||||
arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
|
||||
|
||||
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
|
||||
|
||||
arm9tdmi->arch_info = arm966e;
|
||||
arm966e->common_magic = ARM966E_COMMON_MAGIC;
|
||||
|
||||
/* The ARM966E-S implements the ARMv5TE architecture which
|
||||
* has the BKPT instruction, so we don't have to use a watchpoint comparator
|
||||
*/
|
||||
arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
|
||||
arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
|
||||
|
||||
arm7_9->sw_bkpts_use_wp = 0;
|
||||
arm7_9->sw_bkpts_enabled = 1;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
|
||||
{
|
||||
int chain_pos;
|
||||
char *variant = NULL;
|
||||
arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
ERROR("'target arm966e' requires at least one additional argument");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
chain_pos = strtoul(args[3], NULL, 0);
|
||||
|
||||
if (argc >= 5)
|
||||
variant = args[4];
|
||||
|
||||
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
|
||||
|
||||
arm966e_init_arch_info(target, arm966e, chain_pos, variant);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p)
|
||||
{
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
arm7_9_common_t *arm7_9;
|
||||
arm9tdmi_common_t *arm9tdmi;
|
||||
arm966e_common_t *arm966e;
|
||||
|
||||
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
arm7_9 = armv4_5->arch_info;
|
||||
if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
arm9tdmi = arm7_9->arch_info;
|
||||
if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
arm966e = arm9tdmi->arch_info;
|
||||
if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*armv4_5_p = armv4_5;
|
||||
*arm7_9_p = arm7_9;
|
||||
*arm9tdmi_p = arm9tdmi;
|
||||
*arm966e_p = arm966e;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
|
||||
{
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
||||
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
||||
scan_field_t fields[3];
|
||||
u8 reg_addr_buf = reg_addr & 0x3f;
|
||||
u8 nr_w_buf = 0;
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
arm_jtag_scann(jtag_info, 0xf);
|
||||
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
||||
|
||||
fields[0].device = jtag_info->chain_pos;
|
||||
fields[0].num_bits = 32;
|
||||
fields[0].out_value = NULL;
|
||||
fields[0].out_mask = NULL;
|
||||
fields[0].in_value = NULL;
|
||||
fields[0].in_check_value = NULL;
|
||||
fields[0].in_check_mask = NULL;
|
||||
fields[0].in_handler = NULL;
|
||||
fields[0].in_handler_priv = NULL;
|
||||
|
||||
fields[1].device = jtag_info->chain_pos;
|
||||
fields[1].num_bits = 6;
|
||||
fields[1].out_value = ®_addr_buf;
|
||||
fields[1].out_mask = NULL;
|
||||
fields[1].in_value = NULL;
|
||||
fields[1].in_check_value = NULL;
|
||||
fields[1].in_check_mask = NULL;
|
||||
fields[1].in_handler = NULL;
|
||||
fields[1].in_handler_priv = NULL;
|
||||
|
||||
fields[2].device = jtag_info->chain_pos;
|
||||
fields[2].num_bits = 1;
|
||||
fields[2].out_value = &nr_w_buf;
|
||||
fields[2].out_mask = NULL;
|
||||
fields[2].in_value = NULL;
|
||||
fields[2].in_check_value = NULL;
|
||||
fields[2].in_check_mask = NULL;
|
||||
fields[2].in_handler = NULL;
|
||||
fields[2].in_handler_priv = NULL;
|
||||
|
||||
jtag_add_dr_scan(3, fields, -1, NULL);
|
||||
|
||||
fields[0].in_handler_priv = value;
|
||||
fields[0].in_handler = arm_jtag_buf_to_u32;
|
||||
|
||||
jtag_add_dr_scan(3, fields, -1, NULL);
|
||||
|
||||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
||||
jtag_execute_queue();
|
||||
DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
|
||||
#endif
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
|
||||
{
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
||||
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
||||
scan_field_t fields[3];
|
||||
u8 reg_addr_buf = reg_addr & 0x3f;
|
||||
u8 nr_w_buf = 1;
|
||||
u8 value_buf[4];
|
||||
|
||||
buf_set_u32(value_buf, 0, 32, value);
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
arm_jtag_scann(jtag_info, 0xf);
|
||||
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
||||
|
||||
fields[0].device = jtag_info->chain_pos;
|
||||
fields[0].num_bits = 32;
|
||||
fields[0].out_value = value_buf;
|
||||
fields[0].out_mask = NULL;
|
||||
fields[0].in_value = NULL;
|
||||
fields[0].in_check_value = NULL;
|
||||
fields[0].in_check_mask = NULL;
|
||||
fields[0].in_handler = NULL;
|
||||
fields[0].in_handler_priv = NULL;
|
||||
|
||||
fields[1].device = jtag_info->chain_pos;
|
||||
fields[1].num_bits = 6;
|
||||
fields[1].out_value = ®_addr_buf;
|
||||
fields[1].out_mask = NULL;
|
||||
fields[1].in_value = NULL;
|
||||
fields[1].in_check_value = NULL;
|
||||
fields[1].in_check_mask = NULL;
|
||||
fields[1].in_handler = NULL;
|
||||
fields[1].in_handler_priv = NULL;
|
||||
|
||||
fields[2].device = jtag_info->chain_pos;
|
||||
fields[2].num_bits = 1;
|
||||
fields[2].out_value = &nr_w_buf;
|
||||
fields[2].out_mask = NULL;
|
||||
fields[2].in_value = NULL;
|
||||
fields[2].in_check_value = NULL;
|
||||
fields[2].in_check_mask = NULL;
|
||||
fields[2].in_handler = NULL;
|
||||
fields[2].in_handler_priv = NULL;
|
||||
|
||||
jtag_add_dr_scan(3, fields, -1, NULL);
|
||||
|
||||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
||||
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
|
||||
#endif
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
{
|
||||
int retval;
|
||||
target_t *target = get_current_target(cmd_ctx);
|
||||
armv4_5_common_t *armv4_5;
|
||||
arm7_9_common_t *arm7_9;
|
||||
arm9tdmi_common_t *arm9tdmi;
|
||||
arm966e_common_t *arm966e;
|
||||
arm_jtag_t *jtag_info;
|
||||
|
||||
if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "current target isn't an ARM966e target");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
jtag_info = &arm7_9->jtag_info;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* one or more argument, access a single register (write if second argument is given */
|
||||
if (argc >= 1)
|
||||
{
|
||||
int address = strtoul(args[0], NULL, 0);
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
u32 value;
|
||||
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "couldn't access reg %i", address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
jtag_execute_queue();
|
||||
|
||||
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
u32 value = strtoul(args[1], NULL, 0);
|
||||
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "couldn't access reg %i", address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
int retval;
|
||||
command_t *arm966e_cmd;
|
||||
|
||||
retval = arm9tdmi_register_commands(cmd_ctx);
|
||||
arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
|
||||
register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arm966e.h"
|
||||
|
||||
#include "arm7_9_common.h"
|
||||
#include "register.h"
|
||||
#include "target.h"
|
||||
#include "armv4_5.h"
|
||||
#include "embeddedice.h"
|
||||
#include "log.h"
|
||||
#include "jtag.h"
|
||||
#include "arm_jtag.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if 0
|
||||
#define _DEBUG_INSTRUCTION_EXECUTION_
|
||||
#endif
|
||||
|
||||
/* cli handling */
|
||||
int arm966e_register_commands(struct command_context_s *cmd_ctx);
|
||||
|
||||
/* forward declarations */
|
||||
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
|
||||
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
|
||||
int arm966e_quit(void);
|
||||
|
||||
target_type_t arm966e_target =
|
||||
{
|
||||
.name = "arm966e",
|
||||
|
||||
.poll = arm7_9_poll,
|
||||
.arch_state = armv4_5_arch_state,
|
||||
|
||||
.target_request_data = arm7_9_target_request_data,
|
||||
|
||||
.halt = arm7_9_halt,
|
||||
.resume = arm7_9_resume,
|
||||
.step = arm7_9_step,
|
||||
|
||||
.assert_reset = arm7_9_assert_reset,
|
||||
.deassert_reset = arm7_9_deassert_reset,
|
||||
.soft_reset_halt = arm7_9_soft_reset_halt,
|
||||
.prepare_reset_halt = arm7_9_prepare_reset_halt,
|
||||
|
||||
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
|
||||
|
||||
.read_memory = arm7_9_read_memory,
|
||||
.write_memory = arm7_9_write_memory,
|
||||
.bulk_write_memory = arm7_9_bulk_write_memory,
|
||||
.checksum_memory = arm7_9_checksum_memory,
|
||||
|
||||
.run_algorithm = armv4_5_run_algorithm,
|
||||
|
||||
.add_breakpoint = arm7_9_add_breakpoint,
|
||||
.remove_breakpoint = arm7_9_remove_breakpoint,
|
||||
.add_watchpoint = arm7_9_add_watchpoint,
|
||||
.remove_watchpoint = arm7_9_remove_watchpoint,
|
||||
|
||||
.register_commands = arm966e_register_commands,
|
||||
.target_command = arm966e_target_command,
|
||||
.init_target = arm966e_init_target,
|
||||
.quit = arm966e_quit,
|
||||
};
|
||||
|
||||
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
|
||||
{
|
||||
arm9tdmi_init_target(cmd_ctx, target);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_quit(void)
|
||||
{
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
|
||||
{
|
||||
arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
|
||||
arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
|
||||
|
||||
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
|
||||
|
||||
arm9tdmi->arch_info = arm966e;
|
||||
arm966e->common_magic = ARM966E_COMMON_MAGIC;
|
||||
|
||||
/* The ARM966E-S implements the ARMv5TE architecture which
|
||||
* has the BKPT instruction, so we don't have to use a watchpoint comparator
|
||||
*/
|
||||
arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
|
||||
arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
|
||||
|
||||
arm7_9->sw_bkpts_use_wp = 0;
|
||||
arm7_9->sw_bkpts_enabled = 1;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
|
||||
{
|
||||
int chain_pos;
|
||||
char *variant = NULL;
|
||||
arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
ERROR("'target arm966e' requires at least one additional argument");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
chain_pos = strtoul(args[3], NULL, 0);
|
||||
|
||||
if (argc >= 5)
|
||||
variant = args[4];
|
||||
|
||||
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
|
||||
|
||||
arm966e_init_arch_info(target, arm966e, chain_pos, variant);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p)
|
||||
{
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
arm7_9_common_t *arm7_9;
|
||||
arm9tdmi_common_t *arm9tdmi;
|
||||
arm966e_common_t *arm966e;
|
||||
|
||||
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
arm7_9 = armv4_5->arch_info;
|
||||
if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
arm9tdmi = arm7_9->arch_info;
|
||||
if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
arm966e = arm9tdmi->arch_info;
|
||||
if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*armv4_5_p = armv4_5;
|
||||
*arm7_9_p = arm7_9;
|
||||
*arm9tdmi_p = arm9tdmi;
|
||||
*arm966e_p = arm966e;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
|
||||
{
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
||||
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
||||
scan_field_t fields[3];
|
||||
u8 reg_addr_buf = reg_addr & 0x3f;
|
||||
u8 nr_w_buf = 0;
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
arm_jtag_scann(jtag_info, 0xf);
|
||||
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
||||
|
||||
fields[0].device = jtag_info->chain_pos;
|
||||
fields[0].num_bits = 32;
|
||||
fields[0].out_value = NULL;
|
||||
fields[0].out_mask = NULL;
|
||||
fields[0].in_value = NULL;
|
||||
fields[0].in_check_value = NULL;
|
||||
fields[0].in_check_mask = NULL;
|
||||
fields[0].in_handler = NULL;
|
||||
fields[0].in_handler_priv = NULL;
|
||||
|
||||
fields[1].device = jtag_info->chain_pos;
|
||||
fields[1].num_bits = 6;
|
||||
fields[1].out_value = ®_addr_buf;
|
||||
fields[1].out_mask = NULL;
|
||||
fields[1].in_value = NULL;
|
||||
fields[1].in_check_value = NULL;
|
||||
fields[1].in_check_mask = NULL;
|
||||
fields[1].in_handler = NULL;
|
||||
fields[1].in_handler_priv = NULL;
|
||||
|
||||
fields[2].device = jtag_info->chain_pos;
|
||||
fields[2].num_bits = 1;
|
||||
fields[2].out_value = &nr_w_buf;
|
||||
fields[2].out_mask = NULL;
|
||||
fields[2].in_value = NULL;
|
||||
fields[2].in_check_value = NULL;
|
||||
fields[2].in_check_mask = NULL;
|
||||
fields[2].in_handler = NULL;
|
||||
fields[2].in_handler_priv = NULL;
|
||||
|
||||
jtag_add_dr_scan(3, fields, -1);
|
||||
|
||||
fields[0].in_handler_priv = value;
|
||||
fields[0].in_handler = arm_jtag_buf_to_u32;
|
||||
|
||||
jtag_add_dr_scan(3, fields, -1);
|
||||
|
||||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
||||
jtag_execute_queue();
|
||||
DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
|
||||
#endif
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
|
||||
{
|
||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
||||
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
||||
scan_field_t fields[3];
|
||||
u8 reg_addr_buf = reg_addr & 0x3f;
|
||||
u8 nr_w_buf = 1;
|
||||
u8 value_buf[4];
|
||||
|
||||
buf_set_u32(value_buf, 0, 32, value);
|
||||
|
||||
jtag_add_end_state(TAP_RTI);
|
||||
arm_jtag_scann(jtag_info, 0xf);
|
||||
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
||||
|
||||
fields[0].device = jtag_info->chain_pos;
|
||||
fields[0].num_bits = 32;
|
||||
fields[0].out_value = value_buf;
|
||||
fields[0].out_mask = NULL;
|
||||
fields[0].in_value = NULL;
|
||||
fields[0].in_check_value = NULL;
|
||||
fields[0].in_check_mask = NULL;
|
||||
fields[0].in_handler = NULL;
|
||||
fields[0].in_handler_priv = NULL;
|
||||
|
||||
fields[1].device = jtag_info->chain_pos;
|
||||
fields[1].num_bits = 6;
|
||||
fields[1].out_value = ®_addr_buf;
|
||||
fields[1].out_mask = NULL;
|
||||
fields[1].in_value = NULL;
|
||||
fields[1].in_check_value = NULL;
|
||||
fields[1].in_check_mask = NULL;
|
||||
fields[1].in_handler = NULL;
|
||||
fields[1].in_handler_priv = NULL;
|
||||
|
||||
fields[2].device = jtag_info->chain_pos;
|
||||
fields[2].num_bits = 1;
|
||||
fields[2].out_value = &nr_w_buf;
|
||||
fields[2].out_mask = NULL;
|
||||
fields[2].in_value = NULL;
|
||||
fields[2].in_check_value = NULL;
|
||||
fields[2].in_check_mask = NULL;
|
||||
fields[2].in_handler = NULL;
|
||||
fields[2].in_handler_priv = NULL;
|
||||
|
||||
jtag_add_dr_scan(3, fields, -1);
|
||||
|
||||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
||||
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
|
||||
#endif
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
{
|
||||
int retval;
|
||||
target_t *target = get_current_target(cmd_ctx);
|
||||
armv4_5_common_t *armv4_5;
|
||||
arm7_9_common_t *arm7_9;
|
||||
arm9tdmi_common_t *arm9tdmi;
|
||||
arm966e_common_t *arm966e;
|
||||
arm_jtag_t *jtag_info;
|
||||
|
||||
if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "current target isn't an ARM966e target");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
jtag_info = &arm7_9->jtag_info;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* one or more argument, access a single register (write if second argument is given */
|
||||
if (argc >= 1)
|
||||
{
|
||||
int address = strtoul(args[0], NULL, 0);
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
u32 value;
|
||||
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "couldn't access reg %i", address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
jtag_execute_queue();
|
||||
|
||||
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
u32 value = strtoul(args[1], NULL, 0);
|
||||
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
|
||||
{
|
||||
command_print(cmd_ctx, "couldn't access reg %i", address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm966e_register_commands(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
int retval;
|
||||
command_t *arm966e_cmd;
|
||||
|
||||
retval = arm9tdmi_register_commands(cmd_ctx);
|
||||
arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
|
||||
register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,207 +1,207 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arm_jtag.h"
|
||||
|
||||
#include "binarybuffer.h"
|
||||
#include "log.h"
|
||||
#include "jtag.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
#define _ARM_JTAG_SCAN_N_CHECK_
|
||||
#endif
|
||||
|
||||
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, in_handler_t handler)
|
||||
{
|
||||
jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);
|
||||
|
||||
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
||||
{
|
||||
scan_field_t field;
|
||||
|
||||
field.device = jtag_info->chain_pos;
|
||||
field.num_bits = device->ir_length;
|
||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
field.in_check_value = NULL;
|
||||
field.in_check_mask = NULL;
|
||||
field.in_handler = handler;
|
||||
field.in_handler_priv = NULL;
|
||||
jtag_add_ir_scan(1, &field, -1, NULL);
|
||||
|
||||
|
||||
free(field.out_value);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
|
||||
{
|
||||
if(jtag_info->cur_scan_chain != new_scan_chain)
|
||||
{
|
||||
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
||||
u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);
|
||||
#endif
|
||||
scan_field_t field;
|
||||
|
||||
field.device = jtag_info->chain_pos;
|
||||
field.num_bits = jtag_info->scann_size;
|
||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
||||
jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);
|
||||
#else
|
||||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
|
||||
jtag_add_dr_scan(1, &field, -1, NULL);
|
||||
|
||||
jtag_info->cur_scan_chain = new_scan_chain;
|
||||
|
||||
free(field.out_value);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm_jtag_reset_callback(enum jtag_event event, void *priv)
|
||||
{
|
||||
arm_jtag_t *jtag_info = priv;
|
||||
|
||||
if (event == JTAG_TRST_ASSERTED)
|
||||
{
|
||||
jtag_info->cur_scan_chain = 0;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm_jtag_setup_connection(arm_jtag_t *jtag_info)
|
||||
{
|
||||
jtag_info->scann_instr = 0x2;
|
||||
jtag_info->cur_scan_chain = 0;
|
||||
jtag_info->intest_instr = 0xc;
|
||||
|
||||
jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into host-endian u32, flipping bit-order */
|
||||
int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u32 *dest = priv;
|
||||
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u32, flipping bit-order */
|
||||
int arm_jtag_buf_to_le32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u16, flipping bit-order */
|
||||
int arm_jtag_buf_to_le16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u32, flipping bit-order */
|
||||
int arm_jtag_buf_to_be32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u16, flipping bit-order */
|
||||
int arm_jtag_buf_to_be16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into u8, flipping bit-order */
|
||||
int arm_jtag_buf_to_8_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u8 *dest = priv;
|
||||
*dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* not-flipping variants */
|
||||
/* read JTAG buffer into host-endian u32 */
|
||||
int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u32 *dest = priv;
|
||||
*dest = le_to_h_u32(in_buf);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u32 */
|
||||
int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u16 */
|
||||
int arm_jtag_buf_to_le16(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_le(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u32 */
|
||||
int arm_jtag_buf_to_be32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_be(((u8*)priv), le_to_h_u32(in_buf));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u16 */
|
||||
int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into u8 */
|
||||
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u8 *dest = priv;
|
||||
*dest = le_to_h_u32(in_buf) & 0xff;
|
||||
return ERROR_OK;
|
||||
}
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arm_jtag.h"
|
||||
|
||||
#include "binarybuffer.h"
|
||||
#include "log.h"
|
||||
#include "jtag.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
#define _ARM_JTAG_SCAN_N_CHECK_
|
||||
#endif
|
||||
|
||||
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, in_handler_t handler)
|
||||
{
|
||||
jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);
|
||||
|
||||
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
||||
{
|
||||
scan_field_t field;
|
||||
|
||||
field.device = jtag_info->chain_pos;
|
||||
field.num_bits = device->ir_length;
|
||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
field.in_check_value = NULL;
|
||||
field.in_check_mask = NULL;
|
||||
field.in_handler = handler;
|
||||
field.in_handler_priv = NULL;
|
||||
jtag_add_ir_scan(1, &field, -1);
|
||||
|
||||
|
||||
free(field.out_value);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
|
||||
{
|
||||
if(jtag_info->cur_scan_chain != new_scan_chain)
|
||||
{
|
||||
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
||||
u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);
|
||||
#endif
|
||||
scan_field_t field;
|
||||
|
||||
field.device = jtag_info->chain_pos;
|
||||
field.num_bits = jtag_info->scann_size;
|
||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
|
||||
field.out_mask = NULL;
|
||||
field.in_value = NULL;
|
||||
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
||||
jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);
|
||||
#else
|
||||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
|
||||
jtag_add_dr_scan(1, &field, -1);
|
||||
|
||||
jtag_info->cur_scan_chain = new_scan_chain;
|
||||
|
||||
free(field.out_value);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm_jtag_reset_callback(enum jtag_event event, void *priv)
|
||||
{
|
||||
arm_jtag_t *jtag_info = priv;
|
||||
|
||||
if (event == JTAG_TRST_ASSERTED)
|
||||
{
|
||||
jtag_info->cur_scan_chain = 0;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arm_jtag_setup_connection(arm_jtag_t *jtag_info)
|
||||
{
|
||||
jtag_info->scann_instr = 0x2;
|
||||
jtag_info->cur_scan_chain = 0;
|
||||
jtag_info->intest_instr = 0xc;
|
||||
|
||||
jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into host-endian u32, flipping bit-order */
|
||||
int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u32 *dest = priv;
|
||||
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u32, flipping bit-order */
|
||||
int arm_jtag_buf_to_le32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u16, flipping bit-order */
|
||||
int arm_jtag_buf_to_le16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u32, flipping bit-order */
|
||||
int arm_jtag_buf_to_be32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u16, flipping bit-order */
|
||||
int arm_jtag_buf_to_be16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into u8, flipping bit-order */
|
||||
int arm_jtag_buf_to_8_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u8 *dest = priv;
|
||||
*dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* not-flipping variants */
|
||||
/* read JTAG buffer into host-endian u32 */
|
||||
int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u32 *dest = priv;
|
||||
*dest = le_to_h_u32(in_buf);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u32 */
|
||||
int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into little-endian u16 */
|
||||
int arm_jtag_buf_to_le16(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_le(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u32 */
|
||||
int arm_jtag_buf_to_be32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u32_to_be(((u8*)priv), le_to_h_u32(in_buf));
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into big-endian u16 */
|
||||
int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* read JTAG buffer into u8 */
|
||||
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||
{
|
||||
u8 *dest = priv;
|
||||
*dest = le_to_h_u32(in_buf) & 0xff;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1482
src/target/etb.c
1482
src/target/etb.c
File diff suppressed because it is too large
Load Diff
3726
src/target/etm.c
3726
src/target/etm.c
File diff suppressed because it is too large
Load Diff
4664
src/target/target.c
4664
src/target/target.c
File diff suppressed because it is too large
Load Diff
7598
src/target/xscale.c
7598
src/target/xscale.c
File diff suppressed because it is too large
Load Diff
|
@ -188,9 +188,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
|
|||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
if (device == -1)
|
||||
jtag_add_plain_ir_scan(1, &field, TAP_PI, NULL);
|
||||
jtag_add_plain_ir_scan(1, &field, TAP_PI);
|
||||
else
|
||||
jtag_add_ir_scan(1, &field, TAP_PI, NULL);
|
||||
jtag_add_ir_scan(1, &field, TAP_PI);
|
||||
if (jtag_execute_queue() != ERROR_OK)
|
||||
{
|
||||
tdo_mismatch = 1;
|
||||
|
@ -228,9 +228,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
|
|||
field.in_value = NULL;
|
||||
jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL);
|
||||
if (device == -1)
|
||||
jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);
|
||||
jtag_add_plain_dr_scan(1, &field, TAP_PD);
|
||||
else
|
||||
jtag_add_dr_scan(1, &field, TAP_PD, NULL);
|
||||
jtag_add_dr_scan(1, &field, TAP_PD);
|
||||
if (jtag_execute_queue() != ERROR_OK)
|
||||
{
|
||||
tdo_mismatch = 1;
|
||||
|
@ -302,9 +302,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
|
|||
field.in_value = NULL;
|
||||
jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL);
|
||||
if (device == -1)
|
||||
jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);
|
||||
jtag_add_plain_dr_scan(1, &field, TAP_PD);
|
||||
else
|
||||
jtag_add_dr_scan(1, &field, TAP_PD, NULL);
|
||||
jtag_add_dr_scan(1, &field, TAP_PD);
|
||||
if (jtag_execute_queue() != ERROR_OK)
|
||||
{
|
||||
tdo_mismatch = 1;
|
||||
|
@ -428,9 +428,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
|
|||
field.in_handler = NULL;
|
||||
field.in_handler_priv = NULL;
|
||||
if (device == -1)
|
||||
jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);
|
||||
jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir]);
|
||||
else
|
||||
jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);
|
||||
jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir]);
|
||||
}
|
||||
free(ir_buf);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue