/* */#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>/* * Mac specific includes */#include <NameRegistry.h>#include <Pci.h>#include <Gestalt.h>#include <Timer.h>#include <DriverServices.h>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 <cr> or r<cr> 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 *)&regAdrs, &regAdrsSize);	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(&currentTime);	theTime = ((currentTime.hi  << 32) | currentTime.lo) + timeout;	return theTime;}static long longcurrentTime(void){	UnsignedWide currentTime;	Microseconds(&currentTime);	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 );}