/* */ #include #include #include #include /* * Mac specific includes */ #include #include #include #include #include void findPCICard(char *name); void Jtag_OSDelay(int waitTime); /* miliseconds */ void usDelay(int waitTime); unsigned long swapEndian(unsigned long val); void readConfigEE(unsigned long adr); int jtagError = 0; char *failedRoutineName; void TurnInterruptsOff(void); void TurnInterruptsOn(void); unsigned long aaplAdrs[8]; RegPropertyValueSize adrSize = sizeof(aaplAdrs); char slotName[32]; RegPropertyValueSize nameSize = sizeof(slotName); unsigned long assignedAdrs[8][5]; RegPropertyValueSize assignedAdrsSize = sizeof(assignedAdrs); unsigned long regAdrs[8][5]; RegPropertyValueSize regAdrsSize = sizeof(regAdrs); char *CardNames[] = { "pci1c1c,1", /* winbond (really broken IDE)*/ "pci907f,2015", /* ATronics 2015 (sort of broken IDE)*/ "pci10ad,105", /* Cujo (bus master IDE) */ "pci10b5,9050", /* PLX Eval board */ "pci131f,1034", /* SIIG 2S 1P */ "pci131f,2020", "pci121f,1020", /* SIIG 1P (plx9052) */ "pcid84d,6811", /* Dolphin 1P */ "pcifde5,7", /* Frontier Designs (PLX9050if) */ "pci152c,1", /* Macgraigor PCI JTAG card */ "pci10b5,1", /* MCT-P1P-E */ "pci1407,8000", /* lava ptc-iv */ "" }; unsigned char stateChg[12] = { 0b0000, 0b1000, 0b0000, 0b0100, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b1000 }; volatile unsigned char * LPT0Adr; #define LPD LPT0Adr #define LPS LPT0Adr+1 #define LPC LPT0Adr+2 /* LPS */ #define ASYN 0x08 /* LPC */ #define PSYN 0x01 void outport(volatile unsigned char *adr, unsigned char data); unsigned char inport(volatile unsigned char *adr); #define BUFSIZE 2048 * 1024 unsigned int testbuf[BUFSIZE]; unsigned int obverseCompl(int i) { unsigned int obvCmpl; obvCmpl = (~i & 0000004) << 15; // t00 000 000 000 000 f00 obvCmpl |= (~i & 0000002) << 15; // 0t0 000 000 000 000 0f0 obvCmpl |= (~i & 0000001) << 15; // 00t 000 000 000 000 00f obvCmpl |= (~i & 0000040) << 9; // 000 t00 000 000 f00 000 obvCmpl |= (~i & 0000020) << 9; // 000 0t0 000 000 0f0 000 obvCmpl |= (~i & 0000010) << 9; // 000 00t 000 000 00f 000 obvCmpl |= (~i & 0000400) << 3; // 000 000 t00 f00 000 000 obvCmpl |= (~i & 0000200) << 3; // 000 000 0t0 0f0 000 000 obvCmpl |= (~i & 0000100) << 3; // 000 000 00t 00f 000 000 obvCmpl |= (~i & 0004000) >> 3; // 000 000 f00 t00 000 000 obvCmpl |= (~i & 0002000) >> 3; // 000 000 0f0 0t0 000 000 obvCmpl |= (~i & 0001000) >> 3; // 000 000 00f 00t 000 000 obvCmpl |= (~i & 0040000) >> 9; // 000 f00 000 000 t00 000 obvCmpl |= (~i & 0020000) >> 9; // 000 0f0 000 000 0t0 000 obvCmpl |= (~i & 0010000) >> 9; // 000 00f 000 000 00t 000 obvCmpl |= (~i & 0400000) >> 15; // f00 000 000 000 000 t00 obvCmpl |= (~i & 0200000) >> 15; // 0f0 000 000 000 000 0t0 obvCmpl |= (~i & 0100000) >> 15; // 00f 000 000 000 000 00t return(obvCmpl); } /* * 5 4 3 2 1 0 * 11 10 9 8 7 6 * 17 16 15 14 13 12 -> 5, 11, 17, 4, 10, 16, 3, 9, 15, 2, 8, 14, 1, 7, 13, 0, 6, 12 * */ unsigned int model550(int i) { unsigned int ret; ret = (i & 0000001) << 12; // 00000t00000000000f 12 ret |= (i & 0000002) << 5; // 00000000000t0000f0 6 ret |= (i & 0000004) >> 2; // 000000000000000f0t 0 ret |= (i & 0000010) >> 10; // 0000t000000000f000 13 ret |= (i & 0000020) << 3; // 0000000000t00f0000 7 ret |= (i & 0000040) >> 4; // 000000000000f000t0 1 ret |= (i & 0000100) << 8; // 000t0000000f000000 14 ret |= (i & 0000200) << 1; // 000000000tf0000000 8 ret |= (i & 0000400) >> 6; // 000000000f00000t00 2 ret |= (i & 0001000) << 6; // 00t00000f000000000 15 ret |= (i & 0002000) >> 1; // 0000000ft000000000 9 ret |= (i & 0004000) >> 8; // 000000f0000000t000 3 ret |= (i & 0010000) << 4; // 0t000f000000000000 16 ret |= (i & 0020000) >> 3; // 0000f00t0000000000 10 ret |= (i & 0040000) >> 10; // 000f000000000t0000 4 ret |= (i & 0100000) << 2; // t0f000000000000000 17 ret |= (i & 0200000) >> 5; // 0f0000t00000000000 11 ret |= (i & 0400000) >> 12; // f00000000000t00000 5 return(ret); } void main(void) { int i, j; unsigned int *p; unsigned int *q; unsigned char c; unsigned char c1 = 0x0; unsigned char c2 = 0x80; unsigned char c3 = 0x80; unsigned char c4 = 0x80; unsigned long configAdr; FILE *fp, *fp1; volatile unsigned char * lpd; volatile unsigned char * lps; volatile unsigned char * lpc; unsigned int mkt = 0; unsigned int data = 0; unsigned int blkcnt = 0; unsigned int state = 0; unsigned int cksum = 0; int blklen = 0; int reverse = 0; for(i=0; CardNames[i][0] != '\0'; i++){ findPCICard(CardNames[i]); if(!jtagError) goto foundOne; } printf("didn't find a known card\n"); exit(1); foundOne: printf("%s = %s\n",slotName, CardNames[i]); printf("Slot %s, adrs %x %x %x %x %x %x\n", slotName, aaplAdrs[0], aaplAdrs[1], aaplAdrs[2], aaplAdrs[3], aaplAdrs[4], aaplAdrs[5]); for(i=0; i<8; i++) printf("reg %d %08x,%08x,%08x,%08x,%08x\n", i, regAdrs[i][0],regAdrs[i][1],regAdrs[i][2],regAdrs[i][3],regAdrs[i][4]); for(i=0; i<8; i++) printf("assigned adrs %d %08x,%08x,%08x,%08x,%08x\n", i, assignedAdrs[i][0],assignedAdrs[i][1],assignedAdrs[i][2],assignedAdrs[i][3],assignedAdrs[i][4]); /* for(j=0; j<8; j++){ printf("Adr space %d: 0x%08x\n",j ,aaplAdrs[j]); for(i=0, p = (unsigned char *)aaplAdrs[0]; i<16; i++) printf("%02x ", *p++); printf("\n"); } */ /* * find memory mapped config space */ configAdr = 0; for(i=0; i<8; i++){ if((assignedAdrs[i][0] & 0xff0000ff) == 0x82000010){ configAdr = aaplAdrs[i]; break; } } printf("Config Adr = %08x\n", configAdr); if(configAdr){ readConfigEE(configAdr); } LPT0Adr = 0; for(i=0; i<8; i++){ if((assignedAdrs[i][0] & 0xff0000ff) == 0x81000020){ /* IO Mapped Parallel Port */ LPT0Adr = (volatile unsigned char *)aaplAdrs[i]; break; } } lpd = LPT0Adr; lps = LPT0Adr +1; lpc = LPT0Adr +2; *lpc = 0; // STOP + FIFO RESET *lpd = 0xff; while(1){ blkcnt = 0; state = 0; printf("LPT0 Adr = %08x\n", LPT0Adr); while(1){ printf("Hit or r to start\n"); fflush(stdout); if(!LPT0Adr) exit(1); if((c = getchar()) == 'r') { reverse = 1; getchar();} else reverse = 0; if(c == 'q') exit(1); p = testbuf; data = 0; fp = fopen("test.data","wb"); fp1 = fopen("test.bin","wb"); if(reverse){ *lpc = 0x3; // REV + FIFO RESET usDelay(140000); // UTS delay *lpc = 0x7; // REV + FIFO GO } else{ *lpc = 0x1; // FWD + FIFO RESET usDelay(140000); // UTS delay *lpc = 0x5; // FWD + FIFO GO } /* * STATUS * * 7 1 = EMPTY 0x80 == empty * 6 MARK TRACK * 5 DATA 2 * 4 DATA 1 * 3 DATA 0 * * CTL * * 3 1 = READ/ * 2 0 = RESET FIFO * 1 1 = REV/ * 0 1 = GO/ */ TurnInterruptsOff(); while(1){ if(reverse){ *lpc = 0xf; while((*lps & 0x80) == 0x80); *lpc = 0x7; // FWD/ + FIFO GO + RD/ c = *lps >> 3; *lpc = 0xf; } else{ *lpc = 0xd; while((*lps & 0x80) == 0x80); *lpc = 0x5; // FWD/ + FIFO GO + RD/ c = *lps >> 3; *lpc = 0xd; } mkt = ((mkt<<1) | ((~c & 8) >> 3)) & 0777; data = (data << 3) | (c & 7); /* * * 25 26 32 10 10 10 10 70 70 ... 73 73 73 73 51 45 * blk * |<-- data ---------->| * ck * */ switch(state) { case 0: if(mkt == 0525){ continue; } if(mkt == 0526){ state = 1; cksum = 0; *p++ = mkt; *p++ = data; // block number blkcnt++; continue; } if(mkt == 0222) goto stop; continue; case 1: if(mkt == 0210){ // first 010 state = 2; *p++ = mkt; *p++ = data; } if(mkt == 0222) goto stop; continue; case 2: if(mkt == 0010){ // second 010 state = 3; *p++ = mkt; *p++ = data; } if(mkt == 0222) goto stop; continue; case 3: if(mkt == 0010){ // third 010, first data word state = 4; *p++ = mkt; *p++ = data; cksum ^= data; } if(mkt == 0222) goto stop; continue; case 4: if(mkt == 0010){ state = 5; *p++ = mkt; *p++ = data; cksum ^= data; } if(mkt == 0222) goto stop; continue; case 5: if(mkt == 0070){ state = 5; *p++ = mkt; *p++ = data; cksum ^= data; } if(mkt == 0073){ state = 6; *p++ = mkt; *p++ = data; cksum ^= data; } if(mkt == 0222) goto stop; continue; case 6: if(mkt == 0373){ state = 7; *p++ = mkt; *p++ = data; cksum ^= data; } if(mkt == 0222) goto stop; continue; case 7: if(mkt == 0373){ state = 8; *p++ = mkt; *p++ = data; } if(mkt == 0222) goto stop; continue; case 8: if(mkt == 0351){ state = 9; *p++ = mkt; *p++ = data; } if(mkt == 0222) goto stop; continue; case 9: if(mkt == 0145){ state = 0; *p++ = mkt; *p++ = data; } if(mkt == 0222) goto stop; continue; } } } stop: TurnInterruptsOn(); *lpc = 0; printf("\nend mark detected %d blocks\n", blkcnt); fflush(stdout); state = 0; blkcnt = 0; for(q = testbuf; (unsigned int)q < (unsigned int)p;){ fputc('\n', fp); mkt = *q++ & 077; if(mkt == 026) fputc('\n',fp); data = *q++ & 0777777; i = obverseCompl(data); j = model550(data); fprintf(fp,"%2o %06o %06o %06o state %d ", mkt, data, i, j, state); switch(state){ case 0: if(mkt == 026){ state = 1; cksum = 0; blkcnt++; blklen = 0; } continue; case 1: if(mkt == 010) state = 2; continue; case 2: if(mkt == 010){ state = 3; cksum ^= ((data ) & 077); fprintf(fp, "%02o ", cksum & 077); } continue; case 3: if(mkt == 010){ state = 4; cksum ^= ((data >> 12) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data >> 6) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data ) & 077); fprintf(fp, "%02o", cksum & 077); blklen++; // fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data >> 16) & 0x3,fp1); fputc(0, fp1); } continue; case 4: if(mkt == 010){ state = 5; cksum ^= ((data >> 12) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data >> 6) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data ) & 077); fprintf(fp, "%02o", cksum & 077); blklen++; // fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data >> 16) & 0x3,fp1); fputc(0, fp1); } continue; case 5: if(mkt == 070){ state = 5; cksum ^= ((data >> 12) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data >> 6) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data ) & 077); fprintf(fp, "%02o", cksum & 077); blklen++; // fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data >> 16) & 0x3,fp1); fputc(0, fp1); } if(mkt == 073){ state = 6; cksum ^= ((data >> 12) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data >> 6) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data ) & 077); fprintf(fp, "%02o", cksum & 077); blklen++; // fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data >> 16) & 0x3,fp1); fputc(0, fp1); } continue; case 6: if(mkt == 073){ state = 7; cksum ^= ((data >> 12) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data >> 6) & 077); fprintf(fp, "%02o ", cksum & 077); cksum ^= ((data ) & 077); fprintf(fp, "%02o", cksum & 077); blklen++; // fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data) & 0xff ,fp1); fputc((data >> 8) & 0xff ,fp1); fputc((data >> 16) & 0x3,fp1); fputc(0, fp1); } continue; case 7: if(mkt == 073){ state = 0; cksum ^= ((data >> 12) & 077); fprintf(fp, "blklen %d ", blklen); if(cksum == 077) fprintf(fp, "Parity MATCH"); else{ fprintf(fp," Parity ERROR %02o", cksum); fprintf(stderr,"PERR blk %d\n", blkcnt); } } continue; } } fclose(fp); fclose(fp1); } } void outport(volatile unsigned char *adr, unsigned char data) { *adr = data; } unsigned char inport(volatile unsigned char *adr) { return(*adr); } unsigned short eeBuffer[256]; #define D0 0x4 #define CS 0x2 #define CK 0x1 unsigned char readCmd[] = { CS, CS, D0|CS, D0|CS|CK, D0|CS, D0|CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS, CS|CK, CS, CS }; void readConfigEE(unsigned long adr) { volatile char *p = (volatile char *)(adr + 0x53); /* point to ee access reg */ int i, j; unsigned short inp = 0; for(i=0; i<33; i++){ asm(eieio); *p = readCmd[i]; } for(i=0; i<64; i++){ for(j=0; j<16; j++){ *p = CS; /* lower ck */ asm(eieio); inp = (inp << 1) | ((*p & 0x8) >> 3); /* read a bit */ asm(eieio); *p = CS|CK; /* raise ck */ asm(eieio); *p = CS|CK; /* raise ck */ asm(eieio); *p = CS; /* lower ck */ asm(eieio); *p = CS; /* two ticks */ asm(eieio); } printf("%04x ", inp); if(((i+1) % 16) == 0) printf("\n"); eeBuffer[i] = inp; } *p = 0x20; /* negate CS and clock */ } unsigned long swapEndian(unsigned long val) { return __lwbrx( &val, 0 ); } /* * try to find the PCI JTAG card, and return the register base * adr */ void findPCICard(char *name) { OSErr err; long result; RegEntryID entry; RegEntryIter iter; Boolean done = false; RegEntryIterationOp iterOp = kRegIterDescendants; int i,j; unsigned long val, sav; /* * Check that this is a PCI Mac */ if(Gestalt( gestaltNameRegistryVersion, &result) != noErr) goto fail; RegistryEntryIDInit(&entry); if(RegistryEntryIterateCreate( &iter ) != noErr) goto fail; /* * search the name registry for a PCI card with the correct vendor ID */ err = RegistryEntrySearch(&iter, iterOp, &entry, &done, "name", name, strlen(name)+1); if(err != noErr) goto fail; RegistryEntryIterateDispose(&iter); err = RegistryPropertyGet(&entry, "assigned-addresses", (void *)&assignedAdrs, &assignedAdrsSize); if(err != noErr) goto fail; err = RegistryPropertyGet(&entry, "reg", (void *)®Adrs, ®AdrsSize); if(err != noErr) goto fail; err = RegistryPropertyGet(&entry, "AAPL,address", (void *)&aaplAdrs, &adrSize); if(err != noErr) goto fail; err = RegistryPropertyGet(&entry, "AAPL,slot-name", (void *)&slotName, &nameSize); if(err != noErr) goto fail; /* * card was found, enable I/O and memory space access in PCI config reg at offset 4 */ err = ExpMgrConfigReadLong(&entry, (LogicalAddress)4, &val); val |= 3; err = ExpMgrConfigWriteWord(&entry, (LogicalAddress)4, val); if(err != noErr) goto fail; printf("Config Space\n"); for(j=0; j<128; j+=4){ err = ExpMgrConfigReadLong(&entry, (void *)j, &val); if((j % 16) == 0) printf("\n"); printf("%08x ", val); fflush(stdout); } printf("\n\n"); printf("--\n"); for(i=0; i<6; i++){ err = ExpMgrConfigReadLong(&entry, (void *)((i*4)+0x10), &sav); err = ExpMgrConfigWriteLong(&entry, (void *)((i*4)+0x10), 0xffffffff); err = ExpMgrConfigReadLong(&entry, (void *)((i*4)+0x10), &val); err = ExpMgrConfigWriteLong(&entry, (void *)((i*4)+0x10), sav); printf("%08x = %08x\n",((i*4)+0x10), val); fflush(stdout); } err = ExpMgrConfigReadLong(&entry, (void *)(0x30), &sav); err = ExpMgrConfigWriteLong(&entry, (void *)(0x30), 0xffffffff); err = ExpMgrConfigReadLong(&entry, (void *)(0x30), &val); err = ExpMgrConfigWriteLong(&entry, (void *)(0x30), sav); printf("%08x = %08x (config)\n",0x30, val); printf("--\n"); jtagError = 0; return; fail: jtagError = 1; return; } static long long primeTimeoutTime(int timeout) { UnsignedWide currentTime; long long theTime; Microseconds(¤tTime); theTime = ((currentTime.hi << 32) | currentTime.lo) + timeout; return theTime; } static long long currentTime(void) { UnsignedWide currentTime; Microseconds(¤tTime); return((currentTime.hi << 32) | currentTime.lo); } static void csrTimeout(char *rtn) { failedRoutineName = rtn; jtagError = 1; } /* * Macintosh specific delay() routine */ void Jtag_OSDelay( int waitTime ) { AbsoluteTime startTime, currentDelta; Duration delta; /* get the start time */ startTime = UpTime(); do { /* get the delta absolute time from the start time */ currentDelta = SubAbsoluteFromAbsolute( UpTime(), startTime ); /* convert the delta into micro/milli seconds */ delta = AbsoluteToDuration( currentDelta ); /* if we got microseconds, convert to milliseconds */ if ( delta < 0 ) delta /= -1000; } while( delta < waitTime ); } void usDelay( int waitTime ) { AbsoluteTime startTime, currentDelta; Duration delta; /* get the start time */ startTime = UpTime(); do { /* get the delta absolute time from the start time */ currentDelta = SubAbsoluteFromAbsolute( UpTime(), startTime ); /* convert the delta into micro/milli seconds */ delta = AbsoluteToDuration( currentDelta ); /* at this rate we shouldnt get microseconds, but we'll check for them anyways */ if ( delta > 0 ) delta *= 1000; else delta = -delta; } while( delta < waitTime ); }