00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00031 #include <unistd.h>
00032 #include <sys/io.h>
00033 #include <stdio.h>
00034 #include "pp_jtag.h"
00035
00036 #include <assert.h>
00037
00038
00039 #define OCDEMON_WIGGLER
00040
00041 #ifdef OCDEMON_WIGGLER
00042
00043
00044 #define JTAG_TMS (0x2)
00045 #define JTAG_CLK (0x4)
00046 #define JTAG_TDI (0x8)
00047 #define JTAG_PWR (0x80)
00048 #define JTAG_TRST (0x10)
00049
00050 #define JTAG_TDO (1<<7)
00051 #define JTAG_CPURESET (1)
00052
00053 #endif
00054
00055 #ifdef ALTERAPROG
00056
00057
00058 #define JTAG_TMS (1 << 1)
00059 #define JTAG_CLK (1 << 0)
00060 #define JTAG_TDI (1 << 6)
00061 #define JTAG_PWR (0)
00062 #define JTAG_TRST (0)
00063
00064 #define JTAG_TDO (1<<7)
00065 #define JTAG_CPURESET (0)
00066
00067 #endif
00068
00069 PPJTAG::PPJTAG() : port(0x378), permBits(0x80), jtagRestarted(0) {
00070 }
00071
00072 bool PPJTAG::init(int argc, char **argv) {
00073 static bool first=true;
00074 assert(first);
00075 first=false;
00076 int r = ioperm(port, 3, 1)==0;
00077
00078 #ifdef ALTERAPROG
00079
00080 if (r>=0) {
00081 outb(2, port + 2);
00082 } else {
00083 perror("ioperm");
00084 }
00085 #endif
00086
00087
00088 return r;
00089 }
00090
00091 unsigned char PPJTAG::readJTAG() {
00092 return ~inb(port+1);
00093 }
00094
00095 void PPJTAG::writeJTAG(unsigned char data) {
00096 portVal = data;
00097 outb(data | permBits, port);
00098 }
00099
00100 void PPJTAG::jtagReg(unsigned char *_data, unsigned char length)
00101 {
00102 unsigned char *input_pointer;
00103 unsigned char *output_pointer;
00104 unsigned char count;
00105 unsigned char input=0, value;
00106 unsigned char output = 0;
00107
00108 input_pointer = _data;
00109 output_pointer = _data;
00110
00111
00112 writeJTAG(JTAG_PWR);
00113 writeJTAG(JTAG_PWR | JTAG_CLK);
00114
00115
00116 writeJTAG(JTAG_PWR);
00117 writeJTAG(JTAG_PWR | JTAG_CLK);
00118
00119
00120 for (count = 0; count < length; count ++)
00121 {
00122 if ((count & 0x7) == 0)
00123 {
00124
00125 input = *input_pointer;
00126 input_pointer ++;
00127 }
00128
00129 value = JTAG_PWR;
00130
00131 if (input & 0x01)
00132 value = value | JTAG_TDI;
00133
00134 if (count == (length -1))
00135 {
00136
00137 value = value | JTAG_TMS;
00138 }
00139
00140 writeJTAG(value);
00141 writeJTAG(value | JTAG_CLK);
00142
00143 if ((readJTAG() & JTAG_TDO) != 0)
00144 output = output | (1 << (count & 0x7));
00145
00146 input = input >> 1;
00147
00148 if ((count & 0x7) == 0x7)
00149 {
00150
00151 *output_pointer = output;
00152 output_pointer ++;
00153 output = 0;
00154 }
00155 }
00156
00157 if (length & 0x7)
00158 *output_pointer = output;
00159
00160
00161 writeJTAG(JTAG_PWR | JTAG_TMS);
00162 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00163
00164 #ifdef _FORCE_IDLE_RUN_
00165 if (jtagRestarted)
00166 {
00167 #endif
00168
00169 writeJTAG(JTAG_PWR);
00170 writeJTAG(JTAG_PWR | JTAG_CLK);
00171 writeJTAG(JTAG_PWR);
00172 #ifdef _FORCE_IDLE_RUN_
00173 }
00174 else
00175 {
00176
00177 writeJTAG(JTAG_PWR | JTAG_TMS);
00178 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00179 writeJTAG(JTAG_PWR | JTAG_TMS);
00180 }
00181 #endif
00182 }
00183
00184 void PPJTAG::ireg(unsigned char *_data)
00185 {
00186 #ifdef _FORCE_IDLE_RUN_
00187 if (jtagRestarted == 1)
00188 {
00189
00190 jtagRestarted = 0;
00191 #endif
00192
00193
00194 writeJTAG(JTAG_PWR | JTAG_TMS);
00195 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00196 #ifdef _FORCE_IDLE_RUN_
00197 }
00198 #endif
00199
00200
00201 writeJTAG(JTAG_PWR | JTAG_TMS);
00202 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00203
00204 jtagReg(_data, JTAG_IRLENGTH);
00205 }
00206
00207 void PPJTAG::dreg(unsigned char *data, unsigned char length, bool wonly)
00208 {
00209 #ifdef _FORCE_IDLE_RUN_
00210 if (jtagRestarted == 1)
00211 {
00212
00213 jtagRestarted = 0;
00214 #endif
00215
00216
00217 writeJTAG(JTAG_PWR | JTAG_TMS);
00218 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00219 #ifdef _FORCE_IDLE_RUN_
00220 }
00221 #endif
00222
00223
00224 jtagRestarted = 1;
00225 jtagReg(data, length);
00226
00227 }
00228
00229 void PPJTAG::jtagReset(void)
00230 {
00231 unsigned char loop_count;
00232
00233 trst(true);
00234 trst(false);
00235
00236
00237 writeJTAG(JTAG_PWR);
00238 writeJTAG(JTAG_PWR | JTAG_CLK);
00239
00240 for(loop_count = 0; loop_count < 5; loop_count++)
00241 {
00242
00243 writeJTAG(JTAG_PWR | JTAG_TMS);
00244 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00245 }
00246
00247
00248 writeJTAG(JTAG_PWR);
00249 writeJTAG(JTAG_PWR | JTAG_CLK);
00250 writeJTAG(JTAG_PWR);
00251 writeJTAG(JTAG_PWR | JTAG_CLK);
00252 writeJTAG(JTAG_PWR);
00253
00254 jtagRestarted = 1;
00255 }
00256
00257 void PPJTAG::cpuReset(bool state) {
00258 if (state) {
00259
00260 permBits |= JTAG_CPURESET;
00261 writeJTAG(portVal);
00262 }
00263 else {
00264
00265 permBits &= ~JTAG_CPURESET;
00266 writeJTAG(portVal);
00267 }
00268 }
00269
00270 void PPJTAG::trst(bool state) {
00271 if (!state)
00272 {
00273
00274
00275 permBits|=JTAG_TRST;
00276 writeJTAG(portVal);
00277 }
00278 else
00279 {
00280
00281 permBits&=~JTAG_TRST;
00282 writeJTAG(portVal);
00283 }
00284 }
00285
00286 void PPJTAG::idle(unsigned int nbTCK)
00287 {
00288 unsigned int i;
00289 for (i=0; i<nbTCK; i++)
00290 {
00291 writeJTAG(JTAG_PWR);
00292 writeJTAG(JTAG_PWR | JTAG_CLK);
00293 }
00294 writeJTAG(JTAG_PWR);
00295 }
00296