
JTAG pinout detector
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* 00002 * JTAG pinout detector 00003 * Version 0.1 00004 * 2010-07-15 00005 * 00006 * Copyright (c) 2010 Igor Skochinsky 00007 * 00008 * This software is provided 'as-is', without any express or implied 00009 * warranty. In no event will the authors be held liable for any damages 00010 * arising from the use of this software. 00011 * 00012 * Permission is granted to anyone to use this software for any purpose, 00013 * including commercial applications, and to alter it and redistribute it 00014 * freely, subject to the following restrictions: 00015 * 00016 * 1. The origin of this software must not be misrepresented; you must not 00017 * claim that you wrote the original software. If you use this software 00018 * in a product, an acknowledgment in the product documentation would be 00019 * appreciated but is not required. 00020 * 00021 * 2. Altered source versions must be plainly marked as such, and must not be 00022 * misrepresented as being the original software. 00023 * 00024 * 3. This notice may not be removed or altered from any source 00025 * distribution. 00026 */ 00027 00028 00029 /* 00030 00031 The overall idea: 00032 1) choose any 2 pins as TMS and TCK 00033 2) using them, reset TAP and then shift DR, while observing the state of all other pins 00034 3) for every pin that received anything like a TAP ID (i.e. bit 0 is 1): 00035 4) using the pin as TDI, feed in a known pattern into the TAP 00036 5) keep shifting and monitor the rest of the pins 00037 6) if any of the remaining pins received the pattern, it is TDO 00038 00039 Current algorithm assumes chain length of 1 00040 00041 */ 00042 00043 #include "mbed.h" 00044 00045 00046 // pin description structure 00047 struct PinInfo 00048 { 00049 DigitalInOut pin; 00050 const char *name; 00051 }; 00052 00053 // define the pins to use for bruteforcing 00054 PinInfo g_pins[] = { 00055 {p21, "pin 21", }, 00056 {p22, "pin 22", }, 00057 {p23, "pin 23", }, 00058 {p24, "pin 24", }, 00059 {p25, "pin 25", }, 00060 }; 00061 00062 #define NPINS sizeof(g_pins)/sizeof(g_pins[0]) 00063 00064 // indexes of found pins 00065 int pin_TCK = -1; 00066 int pin_TMS = -1; 00067 int pin_TDO = -1; 00068 int pin_TDI = -1; 00069 00070 inline const char *pinname(int pinno) 00071 { 00072 return pinno == -1 ? "unknown" : g_pins[pinno].name; 00073 } 00074 00075 // print current layout 00076 inline void printpins() 00077 { 00078 printf("TCK: %s, TMS: %s, TDO: %s, TDI: %s\n", 00079 pinname(pin_TCK), pinname(pin_TMS), pinname(pin_TDO), pinname(pin_TDI)); 00080 } 00081 00082 // set pin with a given index 00083 inline void setpin(int pinno, int value) 00084 { 00085 g_pins[pinno].pin.write(value != 0); 00086 } 00087 00088 // read pin with a given index 00089 inline int getpin(int pinno) 00090 { 00091 return g_pins[pinno].pin.read(); 00092 } 00093 00094 // make a pin output pin 00095 inline void makeoutput(int pinno) 00096 { 00097 g_pins[pinno].pin.output(); 00098 } 00099 00100 // make a pin input pin 00101 inline void makeinput(int pinno) 00102 { 00103 g_pins[pinno].pin.input(); 00104 } 00105 00106 // init all pins as inputs 00107 void InitGPIO() 00108 { 00109 for (int i=0; i<NPINS; i++) 00110 makeinput(i); 00111 } 00112 00113 // feed in one tms pulse with given value 00114 void clock_tms(int tms) 00115 { 00116 //TMS is sampled by TAP on the rising edge of TCK, i.e. on change from 0 to 1 00117 //so the proper sequence is TCK=0; TMS=value; TCK=1 00118 setpin(pin_TCK, 0); 00119 setpin(pin_TMS, tms); 00120 //printpins(1); 00121 //Delay(1); 00122 setpin(pin_TCK, 1); 00123 //printpins(1); 00124 setpin(pin_TCK, 0);//to make sure the TDO value gets set 00125 } 00126 00127 // same as above but also set the tdi and return tdo 00128 int clock_tms_tdi(int tms, int tdi) 00129 { 00130 setpin(pin_TCK, 0); 00131 setpin(pin_TMS, tms); 00132 setpin(pin_TDI, tdi); 00133 //printpins(2); 00134 //Delay(1); 00135 setpin(pin_TCK, 1); 00136 //printpins(2); 00137 setpin(pin_TCK, 0);//to make sure the TDO value gets set 00138 return getpin(pin_TDO); 00139 } 00140 00141 // the end 00142 void exit_on_button(char* msg) 00143 { 00144 printf(msg); 00145 while(1); 00146 } 00147 00148 const unsigned int pattern=0xAA55AA55; 00149 00150 void try_tdi(int tdi) 00151 { 00152 int output; 00153 if (tdi==pin_TCK || tdi==pin_TMS || tdi==pin_TDO) 00154 return; 00155 //at this point we know which pin is TDO 00156 //so we'll shift a known pattern into all possible TDIs and monitor the TDO 00157 //since we were shifting in garbage into them during reading the IDCODE, 00158 //we'll skip the 32 bits of output while we're shifting in the pattern 00159 pin_TDI = tdi; 00160 printf("Trying %s as TDI\n", pinname(tdi)); 00161 makeoutput(tdi); 00162 00163 printpins(); 00164 //reset TAP (11111) 00165 puts("Resetting TAP\n"); 00166 clock_tms(1);clock_tms(1);clock_tms(1);clock_tms(1);clock_tms(1); 00167 //go to Shift DR (0100) 00168 puts("Go to Shift DR\n"); 00169 clock_tms(0);clock_tms(1);clock_tms(0);clock_tms(0); 00170 puts("Shifting in pattern.\n"); 00171 00172 for (int i=0; i<32; i++) 00173 { 00174 //printf("%d: ",i); 00175 clock_tms_tdi(0, pattern & (1<<i)); 00176 //puts(stringbuf);putc('\r');putc('\n'); 00177 } 00178 printf("Reading in the output.\n"); 00179 //now keep shifting and read output from TDO 00180 output = 0; 00181 for (int i=0;i<32;i++) 00182 { 00183 //printf("%d: ",i); 00184 output |= getpin(pin_TDO) << i; 00185 clock_tms_tdi(0, 0); 00186 //puts(stringbuf);putc('\r');putc('\n'); 00187 } 00188 printf("Got %08X (expected %08X)\n", output, pattern); 00189 if (output==pattern) 00190 { 00191 printf("Success! Final pinout:\n"); 00192 printpins(); 00193 exit_on_button("Found!"); 00194 } 00195 else if (output!=0 && output!=0xFFFFFFFF) 00196 { 00197 printf("Got some pattern but not ours..."); 00198 } 00199 makeinput(tdi); 00200 } 00201 00202 union idcode_reg { 00203 struct { 00204 unsigned int res: 1; 00205 unsigned int manuf_id: 11; 00206 unsigned int part_no: 16; 00207 unsigned int version: 4; 00208 }; 00209 unsigned int reg32; 00210 }; 00211 00212 // check if we can see a valid TAP id on any of the pins 00213 void try_id() 00214 { 00215 int outputs[NPINS] = {0}; 00216 printf("Trying TCK %s, TMS %s\n", pinname(pin_TCK), pinname(pin_TMS)); 00217 makeoutput(pin_TCK); 00218 makeoutput(pin_TMS); 00219 printpins(); 00220 //reset TAP (11111) 00221 printf("Resetting TAP\n"); 00222 clock_tms(1);clock_tms(1);clock_tms(1);clock_tms(1);clock_tms(1); 00223 //go to Shift DR (0100) 00224 printf("Go to Shift DR\n"); 00225 clock_tms(0);clock_tms(1);clock_tms(0);clock_tms(0); 00226 //shift out the DR 00227 printf("Shifting DR\n"); 00228 //printpins(1); 00229 //puts(stringbuf);putc('\r');putc('\n'); 00230 for (int i=0;i<32;i++) 00231 { 00232 //printf("%d: ",i); 00233 for (int j=0;j<NPINS;j++) 00234 { 00235 if (j!=pin_TCK && j!=pin_TMS) 00236 outputs[j] |= getpin(j) << i; 00237 } 00238 clock_tms(0); 00239 //puts(stringbuf);putc('\r');putc('\n'); 00240 //printpins(1); 00241 } 00242 puts("Done. Checking pin outputs.\n"); 00243 bool found = false; 00244 for (int j=0;j<NPINS;j++) 00245 { 00246 if (j==pin_TCK || j==pin_TMS) 00247 continue; 00248 //printf("%2d: %08X\n", j, outputs[j]); 00249 //check for possible ID code: 32 bits captured are not all zeroes or ones and the 0th bit is 1 00250 if (outputs[j]!=0 && outputs[j]!=0xFFFFFFFF && (outputs[j]&1) ) 00251 { 00252 found = true; 00253 union idcode_reg idc; 00254 idc.reg32 = outputs[j]; 00255 printf("Found a possible TDO on %s. ID code reply is %08X (manufacturer: %02X, part no.: %02X, version: %X)\n", 00256 pinname(j), outputs[j], idc.manuf_id, idc.part_no, idc.version); 00257 pin_TDO = j; 00258 for (int k=0;k<NPINS;k++) 00259 try_tdi(k); 00260 } 00261 } 00262 if ( !found ) 00263 printf("Didn't find any good reply...\n"); 00264 makeinput(pin_TCK); 00265 makeinput(pin_TMS); 00266 } 00267 00268 // try the selected pins 00269 void try_comb(int v[], int maxk) 00270 { 00271 //for (int i=0; i<maxk; i++) printf ("%i ", v[i]); 00272 //printf ("\n"); 00273 pin_TCK = v[0]; 00274 pin_TMS = v[1]; 00275 try_id(); 00276 pin_TCK = v[1]; 00277 pin_TMS = v[0]; 00278 try_id(); 00279 } 00280 00281 // source: http://userweb.cs.utexas.edu/users/djimenez/utsa/cs3343/lecture25.html 00282 void combinations(int v[], int start, int n, int k, int maxk) 00283 { 00284 int i; 00285 /* k here counts through positions in the maxk-element v. 00286 * if k >= maxk, then the v is complete and we can use it. 00287 */ 00288 if ( k >= maxk ) 00289 { 00290 try_comb(v, maxk); 00291 return; 00292 } 00293 00294 /* for this k'th element of the v, try all start..n 00295 * elements in that position 00296 */ 00297 for (i=start; i<n; i++) 00298 { 00299 v[k] = i; 00300 /* recursively generate combinations of integers 00301 * from i+1..n 00302 */ 00303 combinations (v, i+1, n, k+1, maxk); 00304 } 00305 } 00306 00307 int main() 00308 { 00309 int v[NPINS]; 00310 InitGPIO(); 00311 // try all combinations of 2 pins 00312 combinations (v, 0, NPINS, 0, 2); 00313 }
Generated on Tue Jul 12 2022 14:15:19 by
