#include #include #include #include #include #include #include "pcifunc.h" const WORD UNIVIF_VendorID=0x136c; const WORD UNIVIF_DeviceID=0xa026; struct UNIVIFBaseAddr { ULONG config; ULONG IO; ULONG Memory; int bus,dev,fn; }; static UNIVIFBaseAddr univIFBaseAddr[16]; static int Enum_ed=0; static int Init_IO=10; static int GIVEIO=0; static int InitializeIO(int disp=1) { if(Init_IO<10) return Init_IO; int status=getdllstatus(); if(status!=DLLSTATUS_NOERROR) { fprintf(stderr,"Cannot use DLL for PCI access (%d)\n",status); getchar(); Init_IO=-1; return Init_IO; } HANDLE hgiveio; hgiveio = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hgiveio == INVALID_HANDLE_VALUE) { if(disp) printf("Cannot use GiveIO.sys. I'll use PDB functions(will be slow)\n"); } else { GIVEIO=1; CloseHandle(hgiveio); } Init_IO=0; return Init_IO; } static int EnumUNIVIF(int disp=0) { int i,c=0; if(InitializeIO()<0) { return 0; } if(Enum_ed) { for(i=0;i<16;i++) if(univIFBaseAddr[i].config!=0) c++; return c; } for(i=0;i<16;i++) univIFBaseAddr[i].config=0; ULONG cfbase,iobase,membase,BSN; for(i=0;i<20;i++) { ULONG busdevfn=_pciFindPciDevice(UNIVIF_VendorID,UNIVIF_DeviceID,i); if((busdevfn & 0xff) !=0 ) break; int bus=(busdevfn >> 24) & 0xff; int dev=(busdevfn >> 19) & 0x1f; int fn= (busdevfn >> 16) & 0x07; if(disp) printf("Found at BUS:%02X DEV:%02X FN:%02X\t",bus,dev,fn); cfbase=(_pciConfigReadLong(busdevfn >> 16, 0x10))&(~3); // BASE0 iobase=(_pciConfigReadLong(busdevfn >> 16, 0x14))&(~3); // BASE1 membase=(_pciConfigReadLong(busdevfn >> 16, 0x18))&(~0xf); // BASE2 if(disp) printf("C:%04X IO:%04X MEM:%08X\t",cfbase,iobase,membase); BSN=(_IoReadChar(iobase+0xfe) >> 4)&0xf; if(disp) printf("BSN:%d",BSN); if(univIFBaseAddr[BSN].config!=0) fprintf(stderr,"BSN %d is already exist on BUS:%02X DEV:%02X FN:%02X (overwritten).\n", univIFBaseAddr[BSN].bus,univIFBaseAddr[BSN].dev,univIFBaseAddr[BSN].fn); univIFBaseAddr[BSN].config=cfbase; univIFBaseAddr[BSN].IO=iobase; univIFBaseAddr[BSN].Memory=membase; univIFBaseAddr[BSN].bus=bus; univIFBaseAddr[BSN].dev=dev; univIFBaseAddr[BSN].fn=fn; c++; if(disp) puts(""); } Enum_ed=1; return c; } // ==================================================================================== // コンフィギュレーション関数 #include static int _BaseAddress=0x0; const BYTE CONF_DONE=0x01; const BYTE nSTATUS =0x02; const BYTE INIT_DONE=0x04; const BYTE LOOPBACK =0x08; const BYTE nCONFIG =0x01; const BYTE DCLK =0x02; const BYTE DATA =0x04; static byte cur=0xff; inline void outb(BYTE data,WORD port) { if(GIVEIO) _outp(port,data); else _IoWriteChar(port,data); } inline BYTE inb(WORD port) { if(GIVEIO) return (BYTE)_inp(port); else return _IoReadChar(port); } inline void H(byte mask) { cur |= mask; outb(cur,_BaseAddress+0xfe); } inline void L(byte mask) { cur &= ~mask; outb(cur,_BaseAddress+0xfe); } inline int ISH(byte mask) { return inb(_BaseAddress+0xfe)&mask; } inline int ISL(byte mask) { return !ISH(mask); } inline int GetBSN(void) { return (inb(_BaseAddress+0xfe) >> 4)&0xf; } static int CheckLoopBack(void) { H(LOOPBACK); if(!ISH(LOOPBACK)) return 1; L(LOOPBACK); if(!ISL(LOOPBACK)) return 2; return 0; } static int StartConfiguration(int disp) { int i; H(nCONFIG); L(DCLK); L(DATA); L(nCONFIG); for(i=0;i<1000;i++) if((ISL(nSTATUS))&&(ISL(CONF_DONE))) break; if(disp) printf(">> device start-up-time %d\n",i); if(i==1000) { fprintf(stderr,"Start Condition Error(1)\n"); return 1; } H(nCONFIG); for(i=0;i<1000;i++) if(ISH(nSTATUS)) break; if(disp) printf(">> device boot-up-time %d\n",i); if(i==1000) { fprintf(stderr,"Start Condition Error(2)\n"); return 1; } return 0; } inline void SendBit(int bit) { if(bit) H(DATA); else L(DATA); H(DCLK); L(DCLK); } static int SendByte(BYTE b) { int i; for(i=0;i<8;i++) { SendBit(b&1); b=b>>1; if(ISL(nSTATUS)) return -1-i; } return 0; } static int SendData(BYTE *data,int length,int disp) { int i,r,ost=-1; char *progc=".oOo"; for(i=0;i> device status changed %02X at %d\n",ost,i); } if((disp)&&(i%1000==999)) { printf("%c\r",progc[(i/1000)%4]); fflush(stdout); } } for(i=0;i<1000;i++) if(ISH(CONF_DONE)) break; if(disp) printf(">> device configuration-finish-time %d\n",i); if(i==1000) { fprintf(stderr,"Configuration Error(1)\n"); return 1; } return 0; } int UNIVIFConfiguration(int BSN,BYTE *confdata,int length,int disp=0) { if(InitializeIO(disp)<0) { fprintf(stderr,"Cannot initialize I/O libraries\n"); return -1; } EnumUNIVIF(disp); if((BSN<0)||(BSN>15)) { fprintf(stderr,"UIFConfig: BSN must be 0-15\n"); return -2; } if(univIFBaseAddr[BSN].config==0) { fprintf(stderr,"UIFConfig: There is no UnivIF on BSN %d\n",BSN); return -3; } _BaseAddress=univIFBaseAddr[BSN].IO; int r=CheckLoopBack(); if(r!=0) { fprintf(stderr,"UIFConfig: LOOP Back check is failed (code %d)\n",r); return -4; } if(disp) printf("Loop back check on BSN-%d (I/O:%04X): OK\n",BSN,_BaseAddress); if(StartConfiguration(disp)) return -5; if(SendData(confdata,length,disp)) L(nCONFIG); // デバイスdisable if(disp) printf("\n Configuration is successfully done to UNIV-IF(BSN 0x%X)\n\n",BSN); return 0; } BYTE *LoadTTF(const char *filename,int &length) { struct _stat st; if(_stat(filename,&st)<0) { fprintf(stderr,"LoadTTF: No such file %s\n",filename); return NULL; } int size=st.st_size; BYTE *r=new BYTE[size]; length=0; FILE *fp; fp=fopen(filename,"r"); if(fp==NULL) { fprintf(stderr,"LoadTTF: cannot open %s\n",filename); delete [] r; return NULL; } char buff[1024]; while(fgets(buff,1024,fp)) { while(strlen(buff)>0) { if(strchr("\r\n",buff[strlen(buff)-1])) buff[strlen(buff)-1]='\0'; else break; } char *it; for(it=buff ; *it ; it+=4) { if(it[3]=='\0') { it[3]=','; it[4]='\0'; } // 最終数値 if((strchr(" 0123456789",it[0])==NULL) || (strchr(" 0123456789",it[1])==NULL) || (strchr("0123456789",it[2])==NULL) || (it[3]!=',')) { fprintf(stderr,"LoadTTF: Illegal Line in %s\n>>%s\n", filename,buff); fclose(fp); delete []r; return NULL; } r[length]=atoi(it); //printf("%3d,",r[length]); // debug length++; } //printf("\r\n"); // debug } fclose(fp); return r; } int UNIVIFConfigurationFromFile(int BSN,const char *filename,int disp=0) { int len; BYTE *b; b=LoadTTF(filename,len); if(b==NULL) { return 1; } if(disp) printf("Loaded %s (%d bytes)\n",filename,len); UNIVIFConfiguration(BSN,b,len,disp); delete [] b; return 0; } #ifndef USEASLIB int main(int argc,char **argv) { if(argc<3) { puts("univifconf: Universal Interface configuration\n"); puts(" univifconf (-d) \n"); EnumUNIVIF(1); getchar(); return 0; } int disp=0; char *conffile="Not specified.ttf"; int bsn=-1; while(argc>0) { char *endptr; if(strcmp(argv[0],"-d")==0) { disp=1; argc--; argv++; continue; } strtol(argv[0],&endptr,16); if((argc>1)&&(argv[0]!=endptr)) { conffile=argv[1]; bsn=strtol(argv[0],&endptr,16); if(bsn>15) bsn-=6; /* 10進二桁 と 16進一桁の共通か */ if((bsn<0) || (bsn>15)) { fprintf(stderr,"Illegal BSN: %d\n",bsn); return 3; } argv+=2; argc-=2; continue; } argc--; argv++; } if(disp) { puts(""); } UNIVIFConfigurationFromFile(bsn,conffile,disp); return 0; } #endif #if 0 int main(void) { EnumUNIVIF(1); /* // debug int len; BYTE *b; b=LoadTTF("univ_if_cnt.ttf",len); if(b==NULL) { return 2; } printf("Loaded %d bytes\n",len); UNIVIFConfiguration(3,b,len,1);*/ UNIVIFConfigurationFromFile(3,"univ_if_cnt.ttf",1); getchar(); return 0; } #endif