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
__archive__
oharboe 2008-02-25 08:22:18 +00:00
parent 4edcbe0a54
commit 687a9553c9
21 changed files with 21600 additions and 19380 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

1358
src/target/arm11.c Normal file

File diff suppressed because it is too large Load Diff

250
src/target/arm11.h Normal file
View File

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

611
src/target/arm11_dbgtap.c Normal file
View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 = &reg_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 = &reg_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 = &reg_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 = &reg_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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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