/***************************************************************************** * gp32_jtag_linux.c ****************************************************************************/ /* * chains are char* with 0,1 as logic value or -1 as termination * indexes are int* with -1 as termination */ /***************************************************************************** * Includes ****************************************************************************/ #include #include #include #include #include #include /***************************************************************************** * Defines ****************************************************************************/ /* JTAG pins on parallel port */ #define PIN_TCK (0x01) #define PIN_TDI (0x02) #define PIN_TMS (0x04) #define PIN_RST (0x08) #define JtagGetTdo() (((inb(pport + 1) >> 7) ^ 1) & 1) #define MAX_CELLS 1000 #define TYPE_IN (0) #define TYPE_CON (1) #define TYPE_OUT (2) /***************************************************************************** * Typedefs ****************************************************************************/ typedef struct _tag_Cell { char name[256]; int index; int type; int control; } Cell; /***************************************************************************** * Variables ****************************************************************************/ /* I/O port */ unsigned long ports[] = { 0x378, 0x278, 0x3BC, 0 }; unsigned long pport; unsigned char outData; /* instructions */ char EXTEST[] = {0,0,0,0,-1}; /* char BYPASS[] = {1,1,1,1,-1}; not used * char IDCODE[] = {0,1,1,1,-1}; see ID-code verification * char SAMPLE_PRELOAD[] = {1,1,0,0,-1}; not used */ /* cell info */ Cell cells[MAX_CELLS]; int numCells = 0; /* chains */ char initCellValues[MAX_CELLS]; char writeByteCellValues1[MAX_CELLS]; char readByteCellValues1[MAX_CELLS]; char inCellValues[MAX_CELLS]; /* indexes */ int PnWEOutputCells[4]; int PnOEOutputCells[4]; int PnGCSControlCells[16]; int PnGCSOutputCells[16]; int addrControlCells[64]; int addrOutputCells[64]; int dataInputCells[64]; int dataControlCells[64]; int dataOutputCells[64]; char inFileName[255]; char outFileName[255]; unsigned char doWrite = 0; unsigned char doRead = 0; unsigned char compare = 0; char *bsdl[] = { "323 (BC_4, PTOUT(0), input, X)", "322 (BC_1, *, control, 1)", "321 (BC_1, PTOUT(0), output3, X, 322, 1, Z)", "320 (BC_4, PTOUT(1), observe_only, X)", "319 (BC_1, *, control, 1)", "318 (BC_1, PTOUT(1), output3, X, 319, 1, Z)", "317 (BC_4, PTOUT(2), observe_only, X)", "316 (BC_1, *, control, 1)", "315 (BC_1, PTOUT(2), output3, X, 316, 1, Z)", "314 (BC_4, PTOUT(3), observe_only, X)", "313 (BC_1, *, control, 1)", "312 (BC_1, PTOUT(3), output3, X, 313, 1, Z)", "311 (BC_4, PTCLK0, observe_only, X)", "310 (BC_1, *, control, 1)", "309 (BC_1, PTCLK0, output3, X, 310, 1, Z)", "308 (BC_4, PnXDACK(1), observe_only, X)", "307 (BC_1, *, control, 1)", "306 (BC_1, PnXDACK(1), output3, X, 307, 1, Z)", "305 (BC_4, PnXDREQ(1), observe_only, X)", "304 (BC_1, *, control, 1)", "303 (BC_1, PnXDREQ(1), output3, X, 304, 1, Z)", "302 (BC_4, PnXDACK(0), observe_only, X)", "301 (BC_1, *, control, 1)", "300 (BC_1, PnXDACK(0), output3, X, 301, 1, Z)", "299 (BC_4, PnXDREQ(0), observe_only, X)", "298 (BC_1, *, control, 1)", "297 (BC_1, PnXDREQ(0), output3, X, 298, 1, Z)", "296 (BC_4, PI2SLRCK, observe_only, X)", "295 (BC_1, *, control, 1)", "294 (BC_1, PI2SLRCK, output3, X, 295, 1, Z)", "293 (BC_4, PI2SSCLK, observe_only, X)", "292 (BC_1, *, control, 1)", "291 (BC_1, PI2SSCLK, output3, X, 292, 1, Z)", "290 (BC_4, PCCLK, observe_only, X)", "289 (BC_1, *, control, 1)", "288 (BC_1, PCCLK, output3, X, 289, 1, Z)", "287 (BC_4, PI2SSDO, observe_only, X)", "286 (BC_1, *, control, 1)", "285 (BC_1, PI2SSDO, output3, X, 286, 1, Z)", "284 (BC_4, PMMCDAT, observe_only, X)", "283 (BC_1, *, control, 1)", "282 (BC_1, PMMCDAT, output3, X, 283, 1, Z)", "281 (BC_4, PMMCCMD, observe_only, X)", "280 (BC_1, *, control, 1)", "279 (BC_1, PMMCCMD, output3, X, 280, 1, Z)", "278 (BC_4, PMMCCLK, observe_only, X)", "277 (BC_1, *, control, 1)", "276 (BC_1, PMMCCLK, output3, X, 277, 1, Z)", "275 (BC_4, PSPICLK, observe_only, X)", "274 (BC_1, *, control, 1)", "273 (BC_1, PSPICLK, output3, X, 274, 1, Z)", "272 (BC_4, PSPIMISO, observe_only, X)", "271 (BC_1, *, control, 1)", "270 (BC_1, PSPIMISO, output3, X, 271, 1, Z)", "269 (BC_4, PSPIMOSI, observe_only, X)", "268 (BC_1, *, control, 1)", "267 (BC_1, PSPIMOSI, output3, X, 268, 1, Z)", "266 (BC_4, PLEND, observe_only, X)", "265 (BC_1, *, control, 1)", "264 (BC_1, PLEND, output3, X, 265, 1, Z)", "263 (BC_4, PVCLK, observe_only, X)", "262 (BC_1, *, control, 1)", "261 (BC_1, PVCLK, output3, X, 262, 1, Z)", "260 (BC_4, PVLINE, observe_only, X)", "259 (BC_1, *, control, 1)", "258 (BC_1, PVLINE, output3, X, 259, 1, Z)", "257 (BC_4, PVM, observe_only, X)", "256 (BC_1, *, control, 1)", "255 (BC_1, PVM, output3, X, 256, 1, Z)", "254 (BC_4, PVFRAME, observe_only, X)", "253 (BC_1, *, control, 1)", "252 (BC_1, PVFRAME, output3, X, 253, 1, Z)", "251 (BC_4, PVD(0), observe_only, X)", "250 (BC_1, *, control, 1)", "249 (BC_1, PVD(0), output3, X, 250, 1, Z)", "248 (BC_4, PVD(1), observe_only, X)", "247 (BC_1, *, control, 1)", "246 (BC_1, PVD(1), output3, X, 247, 1, Z)", "245 (BC_4, PVD(2), observe_only, X)", "244 (BC_1, *, control, 1)", "243 (BC_1, PVD(2), output3, X, 244, 1, Z)", "242 (BC_4, PVD(3), observe_only, X)", "241 (BC_1, *, control, 1)", "240 (BC_1, PVD(3), output3, X, 241, 1, Z)", "239 (BC_4, PVD(4), observe_only, X)", "238 (BC_1, *, control, 1)", "237 (BC_1, PVD(4), output3, X, 238, 1, Z)", "236 (BC_4, PVD(5), observe_only, X)", "235 (BC_1, *, control, 1)", "234 (BC_1, PVD(5), output3, X, 235, 1, Z)", "233 (BC_4, PVD(6), observe_only, X)", "232 (BC_1, *, control, 1)", "231 (BC_1, PVD(6), output3, X, 232, 1, Z)", "230 (BC_4, PVD(7), observe_only, X)", "229 (BC_1, *, control, 1)", "228 (BC_1, PVD(7), output3, X, 229, 1, Z)", "227 (BC_4, PVD(8), observe_only, X)", "226 (BC_1, *, control, 1)", "225 (BC_1, PVD(8), output3, X, 226, 1, Z)", "224 (BC_4, PVD(9), observe_only, X)", "223 (BC_1, *, control, 1)", "222 (BC_1, PVD(9), output3, X, 223, 1, Z)", "221 (BC_4, PVD(10), observe_only, X)", "220 (BC_1, *, control, 1)", "219 (BC_1, PVD(10), output3, X, 220, 1, Z)", "218 (BC_4, PVD(11), observe_only, X)", "217 (BC_1, *, control, 1)", "216 (BC_1, PVD(11), output3, X, 217, 1, Z)", "215 (BC_4, PVD(12), observe_only, X)", "214 (BC_1, *, control, 1)", "213 (BC_1, PVD(12), output3, X, 214, 1, Z)", "212 (BC_4, PVD(13), observe_only, X)", "211 (BC_1, *, control, 1)", "210 (BC_1, PVD(13), output3, X, 211, 1, Z)", "209 (BC_4, PVD(14), observe_only, X)", "208 (BC_1, *, control, 1)", "207 (BC_1, PVD(14), output3, X, 208, 1, Z)", "206 (BC_4, PVD(15), observe_only, X)", "205 (BC_1, *, control, 1)", "204 (BC_1, PVD(15), output3, X, 205, 1, Z)", "203 (BC_4, PNCTS0, observe_only, X)", "202 (BC_1, *, control, 1)", "201 (BC_1, PNCTS0, output3, X, 202, 1, Z)", "200 (BC_4, PNRTS0, observe_only, X)", "199 (BC_1, *, control, 1)", "198 (BC_1, PNRTS0, output3, X, 199, 1, Z)", "197 (BC_4, PTXD(0), observe_only, X)", "196 (BC_1, *, control, 1)", "195 (BC_1, PTXD(0), output3, X, 196, 1, Z)", "194 (BC_4, PRXD(0), observe_only, X)", "193 (BC_1, *, control, 1)", "192 (BC_1, PRXD(0), output3, X, 193, 1, Z)", "191 (BC_4, PTXD(1), observe_only, X)", "190 (BC_1, *, control, 1)", "189 (BC_1, PTXD(1), output3, X, 190, 1, Z)", "188 (BC_4, PRXD(1), observe_only, X)", "187 (BC_1, *, control, 1)", "186 (BC_1, PRXD(1), output3, X, 187, 1, Z)", "185 (BC_4, *, internal, X)", "184 (BC_4, *, internal, X)", "183 (BC_4, *, internal, X)", "182 (BC_4, *, internal, X)", "181 (BC_4, PEINT(0), observe_only, X)", "180 (BC_1, *, control, 1)", "179 (BC_1, PEINT(0), output3, X, 180, 1, Z)", "178 (BC_4, PEINT(1), observe_only, X)", "177 (BC_1, *, control, 1)", "176 (BC_1, PEINT(1), output3, X, 177, 1, Z)", "175 (BC_4, PEINT(2), observe_only, X)", "174 (BC_1, *, control, 1)", "173 (BC_1, PEINT(2), output3, X, 174, 1, Z)", "172 (BC_4, PEINT(3), observe_only, X)", "171 (BC_1, *, control, 1)", "170 (BC_1, PEINT(3), output3, X, 171, 1, Z)", "169 (BC_4, PEINT(4), observe_only, X)", "168 (BC_1, *, control, 1)", "167 (BC_1, PEINT(4), output3, X, 168, 1, Z)", "166 (BC_4, PEINT(5), observe_only, X)", "165 (BC_1, *, control, 1)", "164 (BC_1, PEINT(5), output3, X, 165, 1, Z)", "163 (BC_4, PEINT(6), observe_only, X)", "162 (BC_1, *, control, 1)", "161 (BC_1, PEINT(6), output3, X, 162, 1, Z)", "160 (BC_4, PEINT(7), observe_only, X)", "159 (BC_1, *, control, 1)", "158 (BC_1, PEINT(7), output3, X, 159, 1, Z)", "157 (BC_4, PnRESET, observe_only, X)", "156 (BC_4, PEXTCLK, observe_only, X)", "155 (BC_4, *, internal, X)", "154 (BC_1, *, internal, X)", "153 (BC_1, *, control, 1)", "152 (BC_1, PSCLK, output3, X, 153, 1, Z)", "151 (BC_1, *, control, 1)", "150 (BC_1, PSCKE, output3, X, 151, 1, Z)", "149 (BC_4, PnWAIT, observe_only, X)", "148 (BC_1, *, control, 1)", "147 (BC_1, PnWAIT, output3, X, 148, 1, Z)", "146 (BC_1, PnGCS(7), output3, X, 153, 1, Z)", "145 (BC_1, PnGCS(6), output3, X, 153, 1, Z)", "144 (BC_1, *, control, 1)", "143 (BC_1, PnGCS(5), output3, X, 144, 1, Z)", "142 (BC_1, *, control, 1)", "141 (BC_1, PnGCS(4), output3, X, 142, 1, Z)", "140 (BC_1, *, control, 1)", "139 (BC_1, PnGCS(3), output3, X, 140, 1, Z)", "138 (BC_1, *, control, 1)", "137 (BC_1, PnGCS(2), output3, X, 138, 1, Z)", "136 (BC_1, *, control, 1)", "135 (BC_1, PnGCS(1), output3, X, 136, 1, Z)", "134 (BC_1, *, control, 1)", "133 (BC_1, PnGCS(0), output3, X, 134, 1, Z)", "132 (BC_1, PnWE, output3, X, 134, 1, Z)", "131 (BC_1, PnOE, output3, X, 134, 1, Z)", "130 (BC_1, PnWBE(0), output3, X, 134, 1, Z)", "129 (BC_1, PnWBE(1), output3, X, 134, 1, Z)", "128 (BC_1, PnWBE(2), output3, X, 134, 1, Z)", "127 (BC_1, PnWBE(3), output3, X, 134, 1, Z)", "126 (BC_1, PnCAS(3), output3, X, 153, 1, Z)", "125 (BC_1, PnCAS(2), output3, X, 153, 1, Z)", "124 (BC_1, *, control, 1)", "123 (BC_1, PnCAS(1), output3, X, 124, 1, Z)", "122 (BC_1, *, control, 1)", "121 (BC_1, PnCAS(0), output3, X, 122, 1, Z)", "120 (BC_1, *, control, 1)", "119 (BC_1, PADDR(0), output3, X, 120, 1, Z)", "118 (BC_1, *, control, 1)", "117 (BC_1, PADDR(1), output3, X, 118, 1, Z)", "116 (BC_1, PADDR(2), output3, X, 118, 1, Z)", "115 (BC_1, PADDR(3), output3, X, 118, 1, Z)", "114 (BC_1, PADDR(4), output3, X, 118, 1, Z)", "113 (BC_1, PADDR(5), output3, X, 118, 1, Z)", "112 (BC_1, PADDR(6), output3, X, 118, 1, Z)", "111 (BC_1, PADDR(7), output3, X, 118, 1, Z)", "110 (BC_1, PADDR(8), output3, X, 118, 1, Z)", "109 (BC_1, PADDR(9), output3, X, 118, 1, Z)", "108 (BC_1, PADDR(10), output3, X, 118, 1, Z)", "107 (BC_1, PADDR(11), output3, X, 118, 1, Z)", "106 (BC_1, PADDR(12), output3, X, 118, 1, Z)", "105 (BC_1, PADDR(13), output3, X, 118, 1, Z)", "104 (BC_1, PADDR(14), output3, X, 118, 1, Z)", "103 (BC_1, PADDR(15), output3, X, 118, 1, Z)", "102 (BC_1, *, control, 1)", "101 (BC_1, PADDR(16), output3, X, 102, 1, Z)", "100 (BC_1, *, control, 1)", "99 (BC_1, PADDR(17), output3, X, 100, 1, Z)", "98 (BC_1, *, control, 1)", "97 (BC_1, PADDR(18), output3, X, 98, 1, Z)", "96 (BC_1, *, control, 1)", "95 (BC_1, PADDR(19), output3, X, 96, 1, Z)", "94 (BC_1, *, control, 1)", "93 (BC_1, PADDR(20), output3, X, 94, 1, Z)", "92 (BC_1, *, control, 1)", "91 (BC_1, PADDR(21), output3, X, 92, 1, Z)", "90 (BC_1, *, control, 1)", "89 (BC_1, PADDR(22), output3, X, 90, 1, Z)", "88 (BC_1, *, control, 1)", "87 (BC_1, PADDR(23), output3, X, 88, 1, Z)", "86 (BC_1, *, control, 1)", "85 (BC_1, PADDR(24), output3, X, 86, 1, Z)", "84 (BC_4, PDATA(0), observe_only, X)", "83 (BC_1, *, control, 1)", "82 (BC_1, PDATA(0), output3, X, 83, 1, Z)", "81 (BC_4, PDATA(1), observe_only, X)", "80 (BC_1, PDATA(1), output3, X, 83, 1, Z)", "79 (BC_4, PDATA(2), observe_only, X)", "78 (BC_1, PDATA(2), output3, X, 83, 1, Z)", "77 (BC_4, PDATA(3), observe_only, X)", "76 (BC_1, PDATA(3), output3, X, 83, 1, Z)", "75 (BC_4, PDATA(4), observe_only, X)", "74 (BC_1, PDATA(4), output3, X, 83, 1, Z)", "73 (BC_4, PDATA(5), observe_only, X)", "72 (BC_1, PDATA(5), output3, X, 83, 1, Z)", "71 (BC_4, PDATA(6), observe_only, X)", "70 (BC_1, PDATA(6), output3, X, 83, 1, Z)", "69 (BC_4, PDATA(7), observe_only, X)", "68 (BC_1, PDATA(7), output3, X, 83, 1, Z)", "67 (BC_4, PDATA(8), observe_only, X)", "66 (BC_1, *, control, 1)", "65 (BC_1, PDATA(8), output3, X, 66, 1, Z)", "64 (BC_4, PDATA(9), observe_only, X)", "63 (BC_1, PDATA(9), output3, X, 66, 1, Z)", "62 (BC_4, PDATA(10), observe_only, X)", "61 (BC_1, PDATA(10), output3, X, 66, 1, Z)", "60 (BC_4, PDATA(11), observe_only, X)", "59 (BC_1, PDATA(11), output3, X, 66, 1, Z)", "58 (BC_4, PDATA(12), observe_only, X)", "57 (BC_1, PDATA(12), output3, X, 66, 1, Z)", "56 (BC_4, PDATA(13), observe_only, X)", "55 (BC_1, PDATA(13), output3, X, 66, 1, Z)", "54 (BC_4, PDATA(14), observe_only, X)", "53 (BC_1, PDATA(14), output3, X, 66, 1, Z)", "52 (BC_4, PDATA(15), observe_only, X)", "51 (BC_1, PDATA(15), output3, X, 66, 1, Z)", "50 (BC_4, PDATA(16), observe_only, X)", "49 (BC_1, *, control, 1)", "48 (BC_1, PDATA(16), output3, X, 49, 1, Z)", "47 (BC_4, PDATA(17), observe_only, X)", "46 (BC_1, *, control, 1)", "45 (BC_1, PDATA(17), output3, X, 46, 1, Z)", "44 (BC_4, PDATA(18), observe_only, X)", "43 (BC_1, *, control, 1)", "42 (BC_1, PDATA(18), output3, X, 43, 1, Z)", "41 (BC_4, PDATA(19), observe_only, X)", "40 (BC_1, *, control, 1)", "39 (BC_1, PDATA(19), output3, X, 40, 1, Z)", "38 (BC_4, PDATA(20), observe_only, X)", "37 (BC_1, *, control, 1)", "36 (BC_1, PDATA(20), output3, X, 37, 1, Z)", "35 (BC_4, PDATA(21), observe_only, X)", "34 (BC_1, *, control, 1)", "33 (BC_1, PDATA(21), output3, X, 34, 1, Z)", "32 (BC_4, PDATA(22), observe_only, X)", "31 (BC_1, *, control, 1)", "30 (BC_1, PDATA(22), output3, X, 31, 1, Z)", "29 (BC_4, PDATA(23), observe_only, X)", "28 (BC_1, *, control, 1)", "27 (BC_1, PDATA(23), output3, X, 28, 1, Z)", "26 (BC_4, PDATA(24), observe_only, X)", "25 (BC_1, *, control, 1)", "24 (BC_1, PDATA(24), output3, X, 25, 1, Z)", "23 (BC_4, PDATA(25), observe_only, X)", "22 (BC_1, *, control, 1)", "21 (BC_1, PDATA(25), output3, X, 22, 1, Z)", "20 (BC_4, PDATA(26), observe_only, X)", "19 (BC_1, *, control, 1)", "18 (BC_1, PDATA(26), output3, X, 19, 1, Z)", "17 (BC_4, PDATA(27), observe_only, X)", "16 (BC_1, *, control, 1)", "15 (BC_1, PDATA(27), output3, X, 16, 1, Z)", "14 (BC_4, PDATA(28), observe_only, X)", "13 (BC_1, *, control, 1)", "12 (BC_1, PDATA(28), output3, X, 13, 1, Z)", "11 (BC_4, PDATA(29), observe_only, X)", "10 (BC_1, *, control, 1)", "9 (BC_1, PDATA(29), output3, X, 10, 1, Z)", "8 (BC_4, PDATA(30), observe_only, X)", "7 (BC_1, *, control, 1)", "6 (BC_1, PDATA(30), output3, X, 7, 1, Z)", "5 (BC_4, PDATA(31), observe_only, X)", "4 (BC_1, *, control, 1)", "3 (BC_1, PDATA(31), output3, X, 4, 1, Z)", "2 (BC_4, PCLKOUT, observe_only, X)", "1 (BC_1, *, control, 1)", "0 (BC_1, PCLKOUT, output3, X, 1, 1, Z)", 0, }; /***************************************************************************** * OpenPort ****************************************************************************/ unsigned long OpenPort ( void ) { // search for valid parallel port int i; i=0; while (ports[i]) { if (!ioperm (ports[i], 3, 1)) { outb(0x55,ports[i]); if (inb(ports[i]) == 0x55) return ports[i]; ioperm (ports[i], 3, 0); } else fprintf (stderr, "ioperm() failed for port %03X\n", ports[i]); i++; } return(0); // return zero if none found } /***************************************************************************** * ClosePort ****************************************************************************/ void ClosePort (void) { ioperm (pport, 3, 0); } /***************************************************************************** * JtagBit ****************************************************************************/ void JtagBit ( int tdi, int tms) { if (tdi) outData |= PIN_TDI; else outData &= ~PIN_TDI; if (tms) outData |= PIN_TMS; else outData &= ~PIN_TMS; outData &= ~PIN_TCK; outb (outData, pport); outData |= PIN_TCK; outb (outData, pport); } /***************************************************************************** * JtagReset ****************************************************************************/ void JtagReset() { int i; outData = PIN_TDI | PIN_TMS | PIN_TCK; outb (outData, pport); usleep (10000); outData = PIN_TDI | PIN_TMS | PIN_RST; outb (outData, pport); usleep (10000); for (i=0; i<5; i++) JtagBit (1,1); } /***************************************************************************** * JtagRunTestIdleState ****************************************************************************/ void JtagRunTestIdleState() { JtagReset(); JtagBit (1,0); /* Run-Test/Idle Status */ JtagBit (1,0); JtagBit (1,0); } /***************************************************************************** * JtagShiftIr ****************************************************************************/ void JtagShiftIr(char *wrIR) { JtagBit (1,1); /* Select-DR-Scan */ JtagBit (1,1); /* Select-IR-Scan */ JtagBit (1,0); /* Capture-IR */ JtagBit (1,0); /* Shift-IR */ while (wrIR[1] >= 0) JtagBit ( *wrIR++, 0); /* Shift-IR */ JtagBit (*wrIR, 1); /* Exit1-IR */ JtagBit (1,1); /* Update-IR */ JtagBit (1,0); /* Run-Test/Idle */ } /***************************************************************************** * JtagShiftDr ****************************************************************************/ void JtagShiftDr(char *wrDR, char *rdDR) { JtagBit (1,1); /* Select-DR-Scan */ JtagBit (1,0); /* Capture-DR */ JtagBit (1,0); /* Shift-DR */ while (wrDR[1] >= 0) { JtagBit (*wrDR++, 0); /* Shift-DR */ *rdDR++ = JtagGetTdo(); } JtagBit (*wrDR, 1); /* Exit1-DR */ *rdDR++ = JtagGetTdo(); *rdDR = -1; JtagBit (1,1); /* Update-DR */ JtagBit (1,0); /* Run-Test/Idle */ } /***************************************************************************** * JtagShiftDr ****************************************************************************/ void JtagShiftDr_dummy(char *wrDR) { JtagBit (1,1); /* Select-DR-Scan */ JtagBit (1,0); /* Capture-DR */ JtagBit (1,0); /* Shift-DR */ while (wrDR[1] >= 0) JtagBit (*wrDR++, 0); /* Shift-DR */ JtagBit (*wrDR, 1); /* Exit1-DR */ JtagBit (1,1); /* Update-DR */ JtagBit (1,0); /* Run-Test/Idle */ } /***************************************************************************** * JtagVerifyId ****************************************************************************/ int JtagVerifyId() { int i; unsigned int id32; JtagReset(); JtagBit (1,0); /* Run-Test/Idle Status */ JtagBit (1,0); /* Run-Test/Idle Status */ JtagBit (1,0); /* Run-Test/Idle Status */ JtagBit (1,0); /* Run-Test/Idle Status */ JtagBit (1,1); /* Select-DR Scan Status */ JtagBit (1,1); /* Select-IR Scan Status */ JtagBit (1,0); /* Capture-IR Status */ JtagBit (1,0); /* Shift-IR Status */ /* S3C24xx IDCODE Instruction "1110" */ JtagBit (0,0); JtagBit (1,0); JtagBit (1,0); JtagBit (1,1); /* Exit1-IR */ JtagBit (1,1); /* Update_IR */ JtagBit (1,1); /* Select-DR-Scan */ JtagBit (1,0); /* Capture-DR */ JtagBit (1,0); /* Shift-DR */ /* Read IDcode */ id32 = 0; for (i=0; i<31; i++) { JtagBit (1,0); /* Shift-DR */ if (JtagGetTdo()) id32 += (1<= 0; cellIndex++) printf("%d", allCells[cellIndex]); printf("\n"); } */ #endif /***************************************************************************** * IndexCells ****************************************************************************/ int IndexCells(char *name, int type, int *indexes) { unsigned char found = 0; int indexCount = 0; int cellIndex; Cell *pCell; pCell = cells; for (cellIndex=0; cellIndexname, name) == 0) { if (pCell->type == type) { found = 1; if (pCell->index >= indexCount) indexCount = pCell->index + 1; indexes[pCell->index] = cellIndex; /*printf("[%d]=%d\n", pCell->index, cellIndex);*/ } } pCell++; } /*printf("name %s, type %d, indexcount %d\n", name, type, indexCount); */ if (!found) { fprintf(stderr, "Cell not found: name %s, type %d\n",name,type); return -1; } indexes[indexCount] = -1; return 0; } /***************************************************************************** * SetCells ****************************************************************************/ void SetCells(char *allCells, int *indexes) { do { allCells[*indexes] = 1; } while (*++indexes >= 0); } /***************************************************************************** * ClearCells ****************************************************************************/ void ClearCells(char *allCells, int *indexes) { do { allCells[*indexes] = 0; } while (*++indexes >= 0); } /***************************************************************************** * SetCells ****************************************************************************/ void SetMultipleCells(char *allCells, int *indexes, unsigned int value) { do { allCells[*indexes] = value & 1; value >>= 1; } while (*++indexes >= 0); } /***************************************************************************** * GetCells ****************************************************************************/ unsigned int GetCells(char *allCells, int *indexes) { unsigned int value = 0, count = 0; do { value = (value >> 1) | (allCells[*indexes] << (sizeof(int)*8 - 1)); count++; } while (*++indexes >= 0); return value >> (sizeof(int)*8 - count); } /***************************************************************************** * SetOutput ****************************************************************************/ int SetOutput(char *allCells, char *name, unsigned int value) { unsigned char found = 0; int cellIndex; Cell *pCell; pCell = cells; for (cellIndex=0; cellIndexname, name) == 0) { found = 1; if (pCell->type == TYPE_OUT) { allCells[cellIndex] = value >> pCell->index & 1; /* printf("%s[%d]\n", pCell->name, pCell->index); */ } else if (pCell->type == TYPE_CON) allCells[cellIndex] = 0; } pCell++; } if (!found) { fprintf(stderr, "Cell not found: name $s\n",name); return -1; } return 0; } /***************************************************************************** * GetInput ****************************************************************************/ #if 0 unsigned int GetInput (char *allCells, char *name) { unsigned char found = 0; unsigned int value = 0; Cell *pCell; pCell = cells; for (int cellIndex=0; cellIndexname, name); */ if (strcmp(pCell->name, name) == 0) { found = 1; if (pCell->type == TYPE_IN) { /* printf("%d", inCellValues1[cellIndex]); */ value |= allCells[cellIndex] << cell.index; /* printf("%s[%d]\n", cell.name, cell.index); */ } else if (pCell->type == TYPE_CON) { allCells[cellIndex] = 1; } else if (pCell->type == TYPE_OUT) { allCells[cellIndex] = 1; } } pCell++; } if (!found) { fprintf(stderr, "Cell not found: name $s\n",name); return -1; } return value; } #endif /***************************************************************************** * BsdlToCells ****************************************************************************/ int BsdlToCells (char *initCellValues) { int cellIndex = -1; char name[256]; int index = -1; char type[256]; char init[256]; int control = -1; Cell *pCell; Cell *pCell_con; char *p; char **s; name[0]='\0'; type[0]='\0'; init[0]='\0'; /* read cellinfo */ for (s=bsdl; *s; s++) { /* read line */ sscanf(*s, "%d %*s %s %s %s %d", &cellIndex, name, type, init, &control); if ((cellIndex < 0) || (cellIndex >= MAX_CELLS)) { fprintf(stderr, "cell index out of range!\n"); return -1; } if (cellIndex >= numCells) { numCells = cellIndex+1; initCellValues[numCells] = -1; } pCell = cells + cellIndex; switch (init[0]) { case '1': initCellValues[cellIndex] = 1; break; case 'X': initCellValues[cellIndex] = 1; break; default: fprintf(stderr, "invalid init value!\n"); return -1; break; } p = strchr(name, '('); if (p) { *p = '\0'; pCell->index = atoi(p+1); } else { p = strchr(name, ','); if (p) *p = '\0'; pCell->index = 0; } strcpy(pCell->name, name); /* printf("%s\n", type); */ if (strcmp(type, "observe_only,") == 0) pCell->type = TYPE_IN; else if (strcmp(type, "input,") == 0) pCell->type = TYPE_IN; else if (strcmp(type, "control,") == 0) pCell->type = TYPE_CON; else if (strcmp(type, "output3,") == 0) pCell->type = TYPE_OUT; else if (strcmp(type, "internal,") == 0) pCell->type = TYPE_IN; /* whatever... */ else { fprintf(stderr, "invalid type value!\n"); return -1; } pCell->control = control; /* printf("pin %s %d\n", name, index); */ } /* copy name/index to control cell */ pCell = cells; for (cellIndex=0; cellIndexcontrol >= 0) { pCell_con = cells + pCell->control; strcpy(pCell_con->name, pCell->name); pCell_con->index = pCell->index; } pCell++; } return 0; } /***************************************************************************** * InitCells ****************************************************************************/ int InitCells() { if (BsdlToCells(initCellValues) < 0) return -1; /* control */ if (IndexCells("PnWE", TYPE_OUT, PnWEOutputCells) < 0) return -1; if (IndexCells("PnOE", TYPE_OUT, PnOEOutputCells) < 0) return -1; /* printf("[%d,%d]\n", PnOEOutputCells[0], PnOEOutputCells[1]); */ if (IndexCells("PnGCS", TYPE_CON, PnGCSControlCells) < 0) return -1; if (IndexCells("PnGCS", TYPE_OUT, PnGCSOutputCells) < 0) return -1; /* address */ if (IndexCells("PADDR", TYPE_CON, addrControlCells) < 0) return -1; if (IndexCells("PADDR", TYPE_OUT, addrOutputCells) < 0) return -1; /* data */ if (IndexCells("PDATA", TYPE_IN, dataInputCells) < 0) return -1; if (IndexCells("PDATA", TYPE_CON, dataControlCells) < 0) return -1; if (IndexCells("PDATA", TYPE_OUT, dataOutputCells) < 0) return -1; /* limit to 8 bits */ dataControlCells[8] = dataInputCells[8] = dataOutputCells[8] = -1; /* bank */ SetMultipleCells(initCellValues, PnGCSControlCells, 0); SetMultipleCells(initCellValues, PnGCSOutputCells, ~1); /* write byte */ memcpy(writeByteCellValues1, initCellValues, numCells+1); SetMultipleCells(writeByteCellValues1, PnWEOutputCells, 0); SetMultipleCells(writeByteCellValues1, dataControlCells, 0); SetMultipleCells(writeByteCellValues1, addrControlCells, 0); /* read byte */ memcpy(readByteCellValues1, initCellValues, numCells+1); SetMultipleCells(readByteCellValues1, PnOEOutputCells, 0); SetMultipleCells(readByteCellValues1, addrControlCells, 0); return 0; } /***************************************************************************** * WriteByte ****************************************************************************/ void WriteByte(unsigned int addr, unsigned int data) { SetMultipleCells(writeByteCellValues1, addrOutputCells, addr); SetMultipleCells(writeByteCellValues1, dataOutputCells, data); JtagShiftDr_dummy(writeByteCellValues1); JtagShiftDr_dummy(initCellValues); } /***************************************************************************** * ReadByte ****************************************************************************/ unsigned char ReadByte(unsigned int addr) { SetMultipleCells(readByteCellValues1, addrOutputCells, addr); JtagShiftDr_dummy(readByteCellValues1); JtagShiftDr(initCellValues, inCellValues); return GetCells(inCellValues, dataInputCells); } void displayUsage(char *thisFilesName) { int i; for(i = strlen(thisFilesName); i >= 0; i--) { if(thisFilesName[i] == '\\') break; } i++; printf("\nUsage: %s (options)\n\n", &thisFilesName[i]); printf(" Where options are any of the following.\n"); /* << " All numbers are in hex.\n" */ printf(" /? Shows this help screen.\n"); printf(" /p biosfile.bin Program biosfile.bin to the GP32's BIOS.\n"); printf(" /d dumpfile.bin Dump the GP32's BIOS to dumpfile.bin.\n"); printf(" /c biosfile.bin Compare the GP32's BIOS to biosfile.bin.\n\n"); } unsigned char parseCmdLine(int argc, char *argv[]) { int a; if(argc <= 1) { displayUsage(argv[0]); return 0; } for (a=1; a < argc; a++) { if ((argv[a][0] == '/') || (argv[a][0] == '-')) { /* option */ switch (tolower(argv[a][1])) { default: case '?': displayUsage(argv[0]); return 0; case 'p': /* program */ a++; if(a >= argc || doRead) { displayUsage(argv[0]); return 0; } doWrite = 1; strncpy(inFileName, argv[a], 254); inFileName[254] = '\0'; break; case 'd': /* dump */ a++; if(a >= argc || doWrite) { displayUsage(argv[0]); return 0; } doRead = 1; strncpy(outFileName, argv[a], 254); outFileName[254] = '\0'; break; case 'c': /* compare */ a++; if(a >= argc || doWrite) { displayUsage(argv[0]); return 0; } compare = 1; strncpy(inFileName, argv[a], 254); inFileName[254] = '\0'; break; } } else { displayUsage(argv[0]); return 0; } } return 1; } /***************************************************************************** * main ****************************************************************************/ int main(int argc, char *argv[]) { unsigned char biosDump[0x80000]; unsigned int size = 0x80000; unsigned char *allData; FILE *f; unsigned char data; unsigned char tempByte; unsigned int addr; int tries; if(!parseCmdLine(argc, argv)) return -1; pport = OpenPort(); if (!pport) { printf ("Couldn't get a parallel port...\n"); return -1; } printf ("Using parallel port at %03X\n",pport); atexit (ClosePort); outData = PIN_TDI | PIN_TDI | PIN_TCK | PIN_RST; outb (outData,pport); if (JtagVerifyId() < 0) return -1; if (InitCells() < 0) return -1; JtagRunTestIdleState(); JtagShiftIr(EXTEST); WriteByte(0x5555, 0xAA); WriteByte(0x2AAA, 0x55); WriteByte(0x5555, 0x90); if ((ReadByte(0x00) != 0x1F) || (ReadByte(0x01) != 0x13)) { fprintf(stderr, "Invalid flash ID\n"); return -1; } WriteByte(0x5555, 0xAA); WriteByte(0x2AAA, 0x55); WriteByte(0x5555, 0xF0); /* erase flash */ if (doWrite) { printf("Erasing...\n"); WriteByte(0x5555, 0xAA); WriteByte(0x2AAA, 0x55); WriteByte(0x5555, 0x80); WriteByte(0x5555, 0xAA); WriteByte(0x2AAA, 0x55); WriteByte(0x5555, 0x10); while (ReadByte(0) != 0xFF); /* 0x10, 0x40, after completion 0xFF */ } if(compare || doWrite) { f = fopen(inFileName, "rb"); if (!f) { fprintf(stderr, "Error opening file!\n"); return -1; } fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); allData = (unsigned char *)malloc(size); if (!allData) { fprintf(stderr, "Out of memory!\n"); return -1; } fread(allData, 1, size, f); fclose(f); } if((compare || doRead) && (size < 0x80000)) { printf("File size is less than BIOS size.\n"); printf("Only reading/comparing 0x%05X bytes.\n",size); } if (doWrite) { printf("Programming 0x%05X bytes to BIOS...\n", size); for (addr=0; addr 20) { printf("\nRetrying address 0x%05X. Wrote 0x%02X but read 0x%02X.\n", addr, data, tempByte); addr--; /* try that addr again */ break; } } while (tempByte != data); /* data polling (bit 7 is complement when busy) */ } printf ("\n"); } else if ((doRead) || (compare)) { if(doRead) printf("Reading 0x%05X bytes from BIOS...\n", size); for (addr=0; addr