X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fjtag.h;h=f3f354a3852105a92deeeacf8eb1861b3dc42576;hp=f5602f1f87b6815c95fcf51c378b0cc177fe183c;hb=526fe3d83e118d87af34353a7140c02f3f1a3c19;hpb=7cdb05b7d6fce73c96e5e7cff3838d6e9c2a07f4 diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index f5602f1f87..f3f354a385 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -2,6 +2,9 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * 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 * @@ -195,15 +198,18 @@ typedef struct jtag_interface_s int (*register_commands)(struct command_context_s *cmd_ctx); int (*init)(void); int (*quit)(void); + /* returns JTAG maxium speed for KHz. 0=RTCK. The function returns + a failure if it can't support the KHz/RTCK. */ + int (*khz)(int khz, int *jtag_speed); + /* returns the KHz for the provided JTAG speed. 0=RTCK. The function returns + a failure if it can't support the KHz/RTCK. */ + int (*speed_div)(int speed, int *khz); } jtag_interface_t; enum jtag_event { - JTAG_SRST_ASSERTED, - JTAG_TRST_ASSERTED, - JTAG_SRST_RELEASED, - JTAG_TRST_RELEASED, + JTAG_TRST_ASSERTED }; extern char* jtag_event_strings[]; @@ -225,6 +231,7 @@ extern enum tap_state end_state; extern enum tap_state cur_state; extern int jtag_speed; +extern int jtag_speed_post_reset; enum reset_types { @@ -240,55 +247,118 @@ enum reset_types extern enum reset_types jtag_reset_config; -/* JTAG subsystem */ +/* initialize interface upon startup. A successful no-op + * upon subsequent invocations + */ +extern int jtag_interface_init(struct command_context_s *cmd_ctx); +/* initialize JTAG chain using only a TLR reset. If init fails, + * try reset + init. + */ extern int jtag_init(struct command_context_s *cmd_ctx); +/* reset, then initialize JTAG chain */ +extern int jtag_init_reset(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); +/* JTAG interface, can be implemented with a software or hardware fifo + * + * TAP_SD and TAP_SI are illegal end states. TAP_SD/SI as end states + * can be emulated by using a larger scan. + * + * Code that is relatively insensitive to the path(as long + * as it is JTAG compliant) taken through state machine can use + * endstate for jtag_add_xxx_scan(). Otherwise the pause state must be + * specified as end state and a subsequent jtag_add_pathmove() must + * be issued. + * + */ +extern void 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 void 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 void 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 void 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. +/* run a TAP_TLR reset. End state is TAP_TLR, regardless + * of start state. + */ +extern void jtag_add_tlr(); +extern int interface_jtag_add_tlr(); +/* Do not use jtag_add_pathmove() unless you need to, but do use it + * if you have to. * - * - A state move from Pause-[ID]R to Shift-[ID]R must not go through - * Update-[ID]R. + * DANGER! If the target is dependent upon a particular sequence + * of transitions for things to work correctly(e.g. as a workaround + * for an errata that contradicts the JTAG standard), then pathmove + * must be used, even if some jtag interfaces happen to use the + * desired path. Worse, the jtag interface used for testing a + * particular implementation, could happen to use the "desired" + * path when transitioning to/from end + * state. * - * - 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 + * 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! + * + * Note that the first on the list must be reachable + * via a single transition from the current state. + * + * All drivers are required to implement jtag_add_pathmove(). + * However, if the pathmove sequence can not be precisely + * executed, an interface_jtag_add_pathmove() or jtag_execute_queue() + * must return an error. It is legal, but not recommended, that + * a driver returns an error in all cases for a pathmove if it + * can only implement a few transitions and therefore + * a partial implementation of pathmove would have little practical + * application. */ -extern int jtag_add_pathmove(int num_states, enum tap_state *path); +extern void 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); +/* go to TAP_RTI, if we're not already there and cycle + * precisely num_cycles in the TAP_RTI after which move + * to the end state, if it is != TAP_RTI + * + * nb! num_cycles can be 0, in which case the fn will navigate + * to endstate via TAP_RTI + */ +extern void 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); +/* A reset of the TAP state machine can be requested. + * + * Whether tms or trst reset is used depends on the capabilities of + * the target and jtag interface(reset_config command configures this). + * + * srst can driver a reset of the TAP state machine and vice + * versa + * + * Application code may need to examine value of jtag_reset_config + * to determine the proper codepath + * + * DANGER! Even though srst drives trst, trst might not be connected to + * the interface, and it might actually be *harmful* to assert trst in this case. + * + * This is why combinations such as "reset_config srst_only srst_pulls_trst" + * are supported. + * + * only req_tlr_or_trst and srst can have a transition for a + * call as the effects of transitioning both at the "same time" + * are undefined, but when srst_pulls_trst or vice versa, + * then trst & srst *must* be asserted together. + */ +extern void jtag_add_reset(int req_tlr_or_trst, int srst); +/* this drives the actual srst and trst pins. srst will always be 0 + * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for + * trst. + * + * the higher level jtag_add_reset will invoke jtag_add_tlr() if + * approperiate + */ extern int interface_jtag_add_reset(int trst, int srst); -extern int jtag_add_end_state(enum tap_state endstate); +extern void 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 void jtag_add_sleep(u32 us); extern int interface_jtag_add_sleep(u32 us); @@ -330,7 +400,6 @@ extern int jtag_register_event_callback(int (*callback)(enum jtag_event event, v extern int jtag_verify_capture_ir; - /* error codes * JTAG subsystem uses codes between -100 and -199 */ @@ -339,34 +408,54 @@ extern int jtag_verify_capture_ir; #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) -/* 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. +/* this allows JTAG devices to implement the entire jtag_xxx() layer in hw/sw */ +#ifdef HAVE_JTAG_MINIDRIVER_H +/* Here a #define MINIDRIVER() and an inline version of hw fifo interface_jtag_add_dr_out can be defined */ +#include "jtag_minidriver.h" +#define MINIDRIVER(a) notused ## a +#else +#define MINIDRIVER(a) a +/* jtag_add_dr_out() is a faster version of jtag_add_dr_scan() * - * So if the end_state!=shift_state, then the transition from shift_state to - * end_state counts as a transition out of shift_state. + * Current or end_state can not be TAP_TLR. end_state can be -1 * - * Legal shift states TAP_SD and TAP_SI + * num_bits[i] is the number of bits to clock out from value[i] LSB first. * - * Legal end state does not include TAP_TLR + * If the device is in bypass, then that is an error condition in + * the caller code that is not detected by this fn, whereas jtag_add_dr_scan() + * does detect it. Similarly if the device is not in bypass, data must + * be passed to it. * - * Bits are clocked out from value LSB first. + * If anything fails, then jtag_error will be set and jtag_execute() will + * return an error. There is no way to determine if there was a failure + * during this function call. + * + * Note that this jtag_add_dr_out can be defined as an inline function. */ -static __inline int jtag_add_shift(const enum tap_state shift_state, const enum tap_state end_state, int bits, u32 value) +extern void interface_jtag_add_dr_out(int device, + int num_fields, + const int *num_bits, + const u32 *value, + enum tap_state end_state); +#endif + + + + +static __inline__ void jtag_add_dr_out(int device, + int num_fields, + const int *num_bits, + const u32 *value, + enum tap_state end_state) { - int retval; - retval=interface_jtag_add_shift(shift_state, end_state, bits, value); - cmd_queue_end_state = end_state; - return retval; + if (end_state != -1) + cmd_queue_end_state=end_state; + cmd_queue_cur_state=cmd_queue_end_state; + interface_jtag_add_dr_out(device, num_fields, num_bits, value, cmd_queue_end_state); }