#include "types.h"
#include "binarybuffer.h"
+#include "log.h"
#include "command.h"
-#if 1
+#if 0
#define _DEBUG_JTAG_IO_
#endif
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 */
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 */
- u8 *in_check_value; /* used to validate scan results */
- u8 *in_check_mask; /* check specified bits against check_value */
- int (*in_handler)(u8 *in_value, void *priv); /* process received buffer using this handler */
+ /* 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 */
*/
int (*execute_queue)(void);
- /* optional command support
- */
- int support_pathmove;
-
/* interface initalization
*/
int (*speed)(int speed);
JTAG_TRST_RELEASED,
};
+extern char* jtag_event_strings[];
+
extern int jtag_trst;
extern int jtag_srst;
extern enum tap_state end_state;
extern enum tap_state cur_state;
-extern char* jtag_interface;
extern int jtag_speed;
enum reset_types
extern int jtag_init(struct command_context_s *cmd_ctx);
extern int jtag_register_commands(struct command_context_s *cmd_ctx);
-/* JTAG interface */
+/* 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 interface_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 interface_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 interface_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);
+extern int interface_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);
+extern int interface_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
+ *
+ * Note! TAP_TLR must not be used in the path!
+ */
extern int jtag_add_pathmove(int num_states, enum tap_state *path);
+extern int interface_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 interface_jtag_add_runtest(int num_cycles, enum tap_state endstate);
extern int jtag_add_reset(int trst, int srst);
+extern int interface_jtag_add_reset(int trst, int srst);
extern int jtag_add_end_state(enum tap_state endstate);
+extern int interface_jtag_add_end_state(enum tap_state endstate);
extern int jtag_add_sleep(u32 us);
+extern int interface_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);
-extern int jtag_cancel_queue(void);
+/* can be implemented by hw+sw */
+extern int interface_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_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_RESET_WOULD_ASSERT_TRST (-105)
#define ERROR_JTAG_RESET_CANT_SRST (-106)
#define ERROR_JTAG_DEVICE_ERROR (-107)
+
+
+/* Here a #define MINIDRIVER() and an inline version of hw fifo interface_jtag_add_shift can be defined */
+
+#ifndef MINIDRIVER
+extern int interface_jtag_add_shift(const enum tap_state shift_state, const enum tap_state end_state, int bits, u32 value);
+#endif
+
+/* Enter the shift_state and cycle "bits" times out of that state.
+ *
+ * So if the end_state!=shift_state, then the transition from shift_state to
+ * end_state counts as a transition out of shift_state.
+ *
+ * Legal shift states TAP_SD and TAP_SI
+ *
+ * Legal end state does not include TAP_TLR
+ *
+ * Bits are clocked out from value LSB first.
+ */
+static __inline int jtag_add_shift(const enum tap_state shift_state, const enum tap_state end_state, int bits, u32 value)
+{
+ int retval;
+ retval=interface_jtag_add_shift(shift_state, end_state, bits, value);
+ return retval;
+}
+
+
#endif /* JTAG_H */