📄 jbijtag.c
字号:
/****************************************************************************/
/* */
/* Module: jbijtag.c */
/* */
/* Copyright (C) Altera Corporation 1998-2000 */
/* */
/* Description: Contains JTAG interface functions */
/* */
/* Revisions: 2.0 added multi-page scan code for 16-bit PORT */
/* */
/****************************************************************************/
#include "jbiport.h"
#include "jbiexprt.h"
#include "jbicomp.h"
#include "jbijtag.h"
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/timex.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#define NULL 0
extern void uwait(unsigned long x);
char *jbi_workspace = NULL;
long jbi_workspace_size = 0L;
/****************************************************************************/
/* */
/* Enumerated Types */
/* */
/****************************************************************************/
/* maximum JTAG IR and DR lengths (in bits) */
#define JBIC_MAX_JTAG_IR_PREAMBLE 256
#define JBIC_MAX_JTAG_IR_POSTAMBLE 256
#define JBIC_MAX_JTAG_IR_LENGTH 512
#define JBIC_MAX_JTAG_DR_PREAMBLE 1024
#define JBIC_MAX_JTAG_DR_POSTAMBLE 1024
#define JBIC_MAX_JTAG_DR_LENGTH 2048
/*
* Global variable to store the current JTAG state
*/
JBIE_JTAG_STATE jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE;
/*
* Store current stop-state for DR and IR scan commands
*/
JBIE_JTAG_STATE jbi_drstop_state = IDLE;
JBIE_JTAG_STATE jbi_irstop_state = IDLE;
/*
* Store current padding values
*/
unsigned int jbi_dr_preamble = 0;
unsigned int jbi_dr_postamble = 0;
unsigned int jbi_ir_preamble = 0;
unsigned int jbi_ir_postamble = 0;
unsigned int jbi_dr_length = 0;
unsigned int jbi_ir_length = 0;
unsigned char *jbi_dr_preamble_data = NULL;
unsigned char *jbi_dr_postamble_data = NULL;
unsigned char *jbi_ir_preamble_data = NULL;
unsigned char *jbi_ir_postamble_data = NULL;
unsigned char *jbi_dr_buffer = NULL;
unsigned char *jbi_ir_buffer = NULL;
/*
* This structure shows, for each JTAG state, which state is reached after
* a single TCK clock cycle with TMS high or TMS low, respectively. This
* describes all possible state transitions in the JTAG state machine.
*/
struct JBIS_JTAG_MACHINE
{
JBIE_JTAG_STATE tms_high;
JBIE_JTAG_STATE tms_low;
} jbi_jtag_state_transitions[] =
{
/* RESET */ { RESET, IDLE },
/* IDLE */ { DRSELECT, IDLE },
/* DRSELECT */ { IRSELECT, DRCAPTURE },
/* DRCAPTURE */ { DREXIT1, DRSHIFT },
/* DRSHIFT */ { DREXIT1, DRSHIFT },
/* DREXIT1 */ { DRUPDATE, DRPAUSE },
/* DRPAUSE */ { DREXIT2, DRPAUSE },
/* DREXIT2 */ { DRUPDATE, DRSHIFT },
/* DRUPDATE */ { DRSELECT, IDLE },
/* IRSELECT */ { RESET, IRCAPTURE },
/* IRCAPTURE */ { IREXIT1, IRSHIFT },
/* IRSHIFT */ { IREXIT1, IRSHIFT },
/* IREXIT1 */ { IRUPDATE, IRPAUSE },
/* IRPAUSE */ { IREXIT2, IRPAUSE },
/* IREXIT2 */ { IRUPDATE, IRSHIFT },
/* IRUPDATE */ { DRSELECT, IDLE }
};
/*
* This table contains the TMS value to be used to take the NEXT STEP on
* the path to the desired state. The array index is the current state,
* and the bit position is the desired endstate. To find out which state
* is used as the intermediate state, look up the TMS value in the
* jbi_jtag_state_transitions[] table.
*/
unsigned short jbi_jtag_path_map[16] =
{
0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFF0F,
0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0x87FF, 0x7FFD
};
/*
* Flag bits for jbi_jtag_io() function
*/
#define TMS_HIGH 1
#define TMS_LOW 0
#define TDI_HIGH 1
#define TDI_LOW 0
#define READ_TDO 1
#define IGNORE_TDO 0
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_init_jtag()
/* */
/****************************************************************************/
{
/* initial JTAG state is unknown */
jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE;
/* initialize global variables to default state */
jbi_drstop_state = IDLE;
jbi_irstop_state = IDLE;
jbi_dr_preamble = 0;
jbi_dr_postamble = 0;
jbi_ir_preamble = 0;
jbi_ir_postamble = 0;
jbi_dr_length = 0;
jbi_ir_length = 0;
if (jbi_workspace != NULL)
{
jbi_dr_preamble_data = (unsigned char *) jbi_workspace;
jbi_dr_postamble_data = &jbi_dr_preamble_data[JBIC_MAX_JTAG_DR_PREAMBLE / 8];
jbi_ir_preamble_data = &jbi_dr_postamble_data[JBIC_MAX_JTAG_DR_POSTAMBLE / 8];
jbi_ir_postamble_data = &jbi_ir_preamble_data[JBIC_MAX_JTAG_IR_PREAMBLE / 8];
jbi_dr_buffer = &jbi_ir_postamble_data[JBIC_MAX_JTAG_IR_POSTAMBLE / 8];
jbi_ir_buffer = &jbi_dr_buffer[JBIC_MAX_JTAG_DR_LENGTH / 8];
}
else
{
jbi_dr_preamble_data = NULL;
jbi_dr_postamble_data = NULL;
jbi_ir_preamble_data = NULL;
jbi_ir_postamble_data = NULL;
jbi_dr_buffer = NULL;
jbi_ir_buffer = NULL;
}
return (JBIC_SUCCESS);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_set_drstop_state
(
JBIE_JTAG_STATE state
)
/* */
/****************************************************************************/
{
jbi_drstop_state = state;
return (JBIC_SUCCESS);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_set_irstop_state
(
JBIE_JTAG_STATE state
)
/* */
/****************************************************************************/
{
jbi_irstop_state = state;
return (JBIC_SUCCESS);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_set_dr_preamble
(
unsigned int count,
unsigned int start_index,
unsigned char *preamble_data
)
/* */
/****************************************************************************/
{
JBI_RETURN_TYPE status = JBIC_SUCCESS;
unsigned int i;
unsigned int j;
if (jbi_workspace != NULL)
{
if (count > JBIC_MAX_JTAG_DR_PREAMBLE)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_dr_preamble = count;
}
}
else
{
if (count > jbi_dr_preamble)
{
jbi_free(jbi_dr_preamble_data);
jbi_dr_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
if (jbi_dr_preamble_data == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_dr_preamble = count;
}
}
else
{
jbi_dr_preamble = count;
}
}
if (status == JBIC_SUCCESS)
{
for (i = 0; i < count; ++i)
{
j = i + start_index;
if (preamble_data == NULL)
{
jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
if (preamble_data[j >> 3] & (1 << (j & 7)))
{
jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
jbi_dr_preamble_data[i >> 3] &=
~(unsigned int) (1 << (i & 7));
}
}
}
}
return (status);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_set_ir_preamble
(
unsigned int count,
unsigned int start_index,
unsigned char *preamble_data
)
/* */
/****************************************************************************/
{
JBI_RETURN_TYPE status = JBIC_SUCCESS;
unsigned int i;
unsigned int j;
if (jbi_workspace != NULL)
{
if (count > JBIC_MAX_JTAG_IR_PREAMBLE)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_ir_preamble = count;
}
}
else
{
if (count > jbi_ir_preamble)
{
jbi_free(jbi_ir_preamble_data);
jbi_ir_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
if (jbi_ir_preamble_data == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_ir_preamble = count;
}
}
else
{
jbi_ir_preamble = count;
}
}
if (status == JBIC_SUCCESS)
{
for (i = 0; i < count; ++i)
{
j = i + start_index;
if (preamble_data == NULL)
{
jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
if (preamble_data[j >> 3] & (1 << (j & 7)))
{
jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
jbi_ir_preamble_data[i >> 3] &=
~(unsigned int) (1 << (i & 7));
}
}
}
}
return (status);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_set_dr_postamble
(
unsigned int count,
unsigned int start_index,
unsigned char *postamble_data
)
/* */
/****************************************************************************/
{
JBI_RETURN_TYPE status = JBIC_SUCCESS;
unsigned int i;
unsigned int j;
if (jbi_workspace != NULL)
{
if (count > JBIC_MAX_JTAG_DR_POSTAMBLE)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_dr_postamble = count;
}
}
else
{
if (count > jbi_dr_postamble)
{
jbi_free(jbi_dr_postamble_data);
jbi_dr_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
if (jbi_dr_postamble_data == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_dr_postamble = count;
}
}
else
{
jbi_dr_postamble = count;
}
}
if (status == JBIC_SUCCESS)
{
for (i = 0; i < count; ++i)
{
j = i + start_index;
if (postamble_data == NULL)
{
jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
if (postamble_data[j >> 3] & (1 << (j & 7)))
{
jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
jbi_dr_postamble_data[i >> 3] &=
~(unsigned int) (1 << (i & 7));
}
}
}
}
return (status);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_set_ir_postamble
(
unsigned int count,
unsigned int start_index,
unsigned char *postamble_data
)
/* */
/****************************************************************************/
{
JBI_RETURN_TYPE status = JBIC_SUCCESS;
unsigned int i;
unsigned int j;
if (jbi_workspace != NULL)
{
if (count > JBIC_MAX_JTAG_IR_POSTAMBLE)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_ir_postamble = count;
}
}
else
{
if (count > jbi_ir_postamble)
{
jbi_free(jbi_ir_postamble_data);
jbi_ir_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
if (jbi_ir_postamble_data == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_ir_postamble = count;
}
}
else
{
jbi_ir_postamble = count;
}
}
if (status == JBIC_SUCCESS)
{
for (i = 0; i < count; ++i)
{
j = i + start_index;
if (postamble_data == NULL)
{
jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
if (postamble_data[j >> 3] & (1 << (j & 7)))
{
jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7));
}
else
{
jbi_ir_postamble_data[i >> 3] &=
~(unsigned int) (1 << (i & 7));
}
}
}
}
return (status);
}
/****************************************************************************/
/* */
void jbi_jtag_reset_idle(void)
/* */
/****************************************************************************/
{
int i;
/*
* Go to Test Logic Reset (no matter what the starting state may be)
*/
for (i = 0; i < 5; ++i)
{
jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
}
/*
* Now step to Run Test / Idle
*/
jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
jbi_jtag_state = IDLE;
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_goto_jtag_state
(
JBIE_JTAG_STATE state
)
/* */
/****************************************************************************/
{
int tms;
int count = 0;
JBI_RETURN_TYPE status = JBIC_SUCCESS;
if (jbi_jtag_state == JBI_ILLEGAL_JTAG_STATE)
{
/* initialize JTAG chain to known state */
jbi_jtag_reset_idle();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -