#if 0 cd [file dirname [info script]] source makefile.tcl return #endif #define FLASH_AMD 0 #define FLASH_INTEL 1 #define FLASH_TYPE FLASH_INTEL #include "type.h" #include "uart.h" #include "b.h" #include "nb.h" #include "zf.h" #include "pci.h" #include "ide.h" #include "ohci.h" #if (FLASH_TYPE==FLASH_AMD) #include "flashAmd.h" #elif (FLASH_TYPE==FLASH_INTEL) #include "flashIntel.h" #endif #ifdef _bios #include "ohci.h" #include "fei82559.h" #include "config.h" #include "ethernet.h" #include "ip.h" #include "udp.h" #include "tftp.h" #include "socketUdp.h" #include "debug.h" #endif //U8 flashImage[32*1024]; U8* const flashImage=(U8*)0x100000; void cmdFlash(U32 addr,U32 data); void cmdDiff(U32 *src,U32 *dst,U32 data); void flashMap(U32 address) { #if (FLASH_TYPE==FLASH_AMD) #define flash (*(FlashAmd *)0x000e0000) #elif (FLASH_TYPE==FLASH_INTEL) #define flash (*(FlashIntel *)0x000e0000) #endif zfRegs->memoryWindows[0].base=(U32)flash.base; zfRegs->memoryWindows[0].size=0x00010000-1; zfRegs->memoryWindows[0].page=(0x01000000-(U32)flash.base)+address; /* com1 << "mem base 0 : " << zfRegs->memoryWindows[0].base << "\n\r"; com1 << "mem size 0 : " << zfRegs->memoryWindows[0].size << "\n\r"; com1 << "mem page 0 : " << zfRegs->memoryWindows[0].page << "\n\r"; */ nbRegs->shadowRamReadEnable=0; nbRegs->shadowRamWriteEnable=0; /* com1 << "shadowRamReadEnable : " << nbRegs->shadowRamReadEnable << "\n\r"; com1 << "shadowRamWriteEnable : " << nbRegs->shadowRamWriteEnable << "\n\r"; */ } U32 scanU32(U8 *s,U32 base) { U8 car; U32 v=0; while((car=*s++)) { v*=base; if(car-'0'<10) { v+=car-'0'; } else if(car-'a'<26) { v+=car-'a'+10; } else if(car-'A'<26) { v+=car-'A'+10; } else break; } return v; } U32 scanU32(U8 *s) { U8 base=10; if(!*s) return 0; if(*s=='0') { base=8; s++; if(!*s) return 0; if(*s=='x') { base=16; s++; } } return scanU32(s,base); } U32 parse(U8 *line,U8 **argv,U32 argc) { U32 argd=argc; U8 *dst,c; argc=0; dst=line; while(*line && argd) { while(*line && *line==' ') { line++; } if(*line=='\0') break; argv[argc]=dst; argc++; argd--; while((c=*line++) && c!=' ') { if(c=='\\') { c=*line++; if(((unsigned)(c-'0'))<10) { c=0; if(*line) c+= *line++-'0'; if(*line) c<<=3,c+= *line++-'0'; if(*line) c<<=3,c+= *line++-'0'; } else switch(c) { case '\\': c='\\'; break; case 'n': c='\n'; break; case 't': c='\t'; break; case 'e': c='\x1b'; break; case 'x': c=0; if(*line) c+= ((unsigned)(*line-'0'))<10 ? (*line++-'0') : ((unsigned)(*line-'a'))<6 ? (*line++-'a')+10 : (*line++-'A')+10; if(*line) c<<=4,c+= ((unsigned)(*line-'0'))<10 ? (*line++-'0') : ((unsigned)(*line-'a'))<6 ? (*line++-'a')+10 : (*line++-'A')+10; default : ; } } *dst++=c; } *dst++='\0'; if(!c) break; } return argc; } int test(U32 argc,U8 **argv,char *fmt,U32 *cnt,...) { U32 **args=(U32 **)(&cnt+1); U8 *arg; if(!argc) return 0; if(bCmp(*argv,(U8*)"help",5)==0) { com1 << fmt << '\r' << '\n'; return 0; } arg=*argv; while(*fmt && *fmt!=' ') { if(*fmt++!=*arg++) return 0; } if(*arg!='\0') return 0; while(*fmt==' ') fmt++; argc--; argv++; *cnt=0; while(argc && *fmt) { switch(*fmt++) { case 'u' : **args=scanU32(*argv); break; case 's' : *(U8**)*args=*argv; default: ; } (*cnt)++; argc--; argv++; args++; } return 1; } struct CCall { volatile U32 (*function)(U32,U32,U32,U32,U32,U32,U32,U32,U32,U32); volatile U32 result; volatile U32 args[10]; inline void init() { function=0; asm("wbinvd"); } inline bool got() { asm("invd"); return (bool)function; } inline U32 execute() { result=(*function)( args[0],args[1],args[2],args[3],args[4], args[5],args[6],args[7],args[8],args[9]); function=0; asm("wbinvd"); return result; } }; void cmdLine(U8 *,U32 len,CCall *cCall); void cmdLines(); void gotStack(U32 end,U32 begin) { extern const char biosName[]; com1.init(); com1 << biosName << "\n\r"; com1 << "stack : " << end << " ... " << begin << " " << (U32)&end <<"\r\n"; configurate(); cmdLines(); /* page fault */ *((U32*)-1)=0; } Fei82559 *fei82559; void cmdLines() { const U32 cmdSize=128; U8 cmd[cmdSize]; U32 len; CCall cCall; Fei82559 _fei82559; com1<<"cCall @"<<(U32)&cCall<<" if not null\r\n"; cCall.init(); _fei82559.hw=fei82559Hw; fei82559= fei82559Hw ? &_fei82559 : 0 ; if(fei82559) fei82559->init(); com1 << '>'; // << ' '; len=0; while(1) { if(cCall.got()) { cCall.execute(); // com1<< cCall.execute() << '\r'<<'\n'; } if(com1.gotChar()) { cmd[len]=com1.getChar(); if(cmd[len]=='\r') { com1.sendChar('\r'); com1.sendChar('\n'); cmd[len]='\0'; if(len==4 && bCmp(cmd,(U8*)"quit",len)==0) break; cmdLine(cmd,len,&cCall); com1 << '>'; // << ' '; len=0; } else if(cmd[len]==8) { if(len) { com1.sendChar(8); com1.sendChar(' '); com1.sendChar(8); len--; } } else { com1.sendChar(cmd[len]); len++; } } } } void cmdLine(U8 *cmd,U32 len,CCall *cCall) { U8 *argv[16]; U32 argc; U32* src; U32* dst; U8* string; U32 data; U32 addr; U32 bus,slot,func; argc=parse(cmd,argv,16); if(argc==0) { // rien } else if(test(argc,argv,"i uu",&argc,&addr,&data)) { if(argc==1) data=*(Io*)addr; else *(Io*)addr=data; com1 << ( argc==1 ? "in ":"out" ) << " long @" << U16(addr) << '=' << data << "\r\n"; } else if(test(argc,argv,"m uu",&argc,&addr,&data)) { if(argc==1) data=*(U32*)addr; else *(U32*)addr=data; com1 << ( argc==1 ? "rd":"wr" ) << " long @" << addr << '=' << data << "\r\n"; } else if(test(argc,argv,"dump uu",&argc,&addr,&data)) { if(argc==2) com1.dump((U8*)addr,data,addr); } else if(test(argc,argv,"yload u",&argc,&addr)) { if(argc<1) addr=(U32)flashImage; com1.yload((U8*)addr); } else if(test(argc,argv,"freset",&argc)) { flash.reset(); com1 << "manufactorId : " << flash.manufactorId() << "\n\r"; flash.reset(); com1 << "deviceId : " << flash.deviceId() << "\n\r"; flash.reset(); } else if(test(argc,argv,"ferase",&argc)) { com1 << "erase : " << flash.erase() << "\r\n"; } else if(test(argc,argv,"flash uu",&argc,&addr,&data)) { if(argc<1) addr=(U32)flashImage; if(argc<2) data=sizeof(flashImage); cmdFlash(addr,data); } else if(test(argc,argv,"diff uuu",&argc,&src,&dst,&data)) { if(argc<1) src=(U32*)flashImage; if(argc<2) dst=(U32*)(0x0f0000-sizeof(flashImage)); if(argc<3) data=sizeof(flashImage); cmdDiff(src,dst,data); } else if(test(argc,argv,"call uuuuuuuuuuu",&argc,&cCall->function, cCall->args+0,cCall->args+1,cCall->args+2,cCall->args+3,cCall->args+4, cCall->args+5,cCall->args+6,cCall->args+7,cCall->args+8,cCall->args+9)) { com1<< cCall->execute() << '\r'<<'\n'; } else if(test(argc,argv,"memtest uuu",&argc,&src,&dst,&data)) { if(argc<1) src=(U32*)0x300000; if(argc<2) dst=(U32*)0x300000; if(argc<3) data=0x100000; data/=sizeof(U32); for(U32 i=0;iregs[addr] << "\r\n"; } } else if(test(argc,argv,"pd u",&argc,&bus)) { if(argc<1) bus=0; func=0; for(slot=0;slot<32;slot++) { data=PciConf::bsf(bus,slot,func)->vendorDeviceId; if(data!=0xffffffff) { com1 << (U8)bus << ' ' << (U8)slot << ' ' << (U8)func << ' ' << data << "\r\n"; } } } #if 0 else if(test(argc,argv,"ide",&argc)) { U8 buf[0x200]; bFill(buf,0,0x200); if(ide->identify(buf,0x200)) { com1.dump(buf,0x200); } } #endif else if(test(argc,argv,"nbdump u",&argc,&addr)) { U16 buf[0x100],*pt; U32 dcnt=0x100; bFill((U8*)buf,0,sizeof(buf)); if(!argc) addr=0x100; pt=buf; while(dcnt--) { *pt=*(Nb16*)addr; pt++; addr++; } com1.dump((U8*)buf,sizeof(buf),addr-0x100,sizeof(U16)); } else if(test(argc,argv,"flashMap",&argc,&addr)) { if(!argc) addr=0x00070000; flashMap(addr); } else /* if(test(argc,argv,"ohciInit",&argc,&addr)) { waitQuadletInit((Ohci *)0xe0000000); } else if(test(argc,argv,"ohciPoll",&argc,&addr)) { waitQuadletPoll((Ohci *)0xe0000000); } else */ if(test(argc,argv,"cacheFlush",&argc)) { asm("wbinvd"); } else if(test(argc,argv,"cacheInvalidate",&argc)) { asm("invd"); } else if(fei82559 && test(argc,argv,"fei_eeprom u",&argc,&addr)) { if(argc!=1) addr=0; data=0; fei82559Hw->eeprom->read(addr,&data); com1 << "@" << addr << "=" << data << "\r\n"; } else if(fei82559 && test(argc,argv,"fei_dump",&argc,&addr)) { fei82559Hw->dump(); } else if(fei82559 && test(argc,argv,"fei_debug u",&argc,&data)) { if(argc!=1) data=0; extern int debug_fei82559; debug_fei82559=data; com1 << "debug_fei82559 = " << debug_fei82559 << "\r\n"; } else if(test(argc,argv,"tftp us",&argc,&addr,&string)) { if(!fei82559) return; if(argc<2) string=(U8*)"linux"; if(argc<1) addr=0x100000; TftpClient tftpc; com1 << "tftp\r\n"; tftpc.readFile(fei82559,(U8*)addr,string); } else if(test(argc,argv,"udp s",&argc,&string)) { if(!fei82559) return; static const Ethernet::Address ethServer={{0x00,0xc0,0xa8,0x7c,0x3c,0xec}}; static const Ethernet::Address ethClient={{0x00,0x13,0x95,0x00,0x00,0x4a}}; static const Ip::Address ipServer={{192,168,0,1}}; static const Ip::Address ipClient={{192,168,0,3}}; /* static const U8 data[]="coucou !"; static const U32 len=sizeof(data); */ SocketUdp sock; U32 len; sock.local.ethernet = ethClient; sock.local.ip = ipClient; sock.local.port = 1024; sock.distant.ethernet = ethServer; sock.distant.ip = ipServer; sock.distant.port = 2048; sock.ec=fei82559; if(argc) { { U8 *pt=string; len=0; while(*pt++) len++; } sock.send(string,len); } else { U8 buf[128]; len=sock.recv(buf,sizeof(buf)); if(len!=~0U) { com1.sendString(buf,len)<<"\r\n"; } } } else if(bCmp(*argv,(U8*)"help",4)!=0) { com1 << "hein ?\r\n"; } } U32 memRead(U32 *address) { return *address; } U32 memWrite(U32 *address,U32 value) { *address=value; return 0; } U32 ioRead(U32 *address) { return *(Io*)address; } U32 ioWrite(U32 *address,U32 value) { *(Io*)address=value; return 0; } U32 pciRead(U32 bus,U32 slot,U32 func,U32 address) { return PciConf::bsf(bus,slot,func)->regs[address/sizeof(U32)]; } U32 pciWrite(U32 bus,U32 slot,U32 func,U32 address,U32 data) { PciConf::bsf(bus,slot,func)->regs[address/sizeof(U32)]=data; return 0; } void cmdFlash(U32 addr,U32 data) { U32 dcnt=10; com1 << "writing " << data << " bytes ...\r\n"; #if (FLASH_TYPE==FLASH_AMD) U16 *pt= (U16*)addr,v; addr=0x10000-data; while(data--) { dcnt=10; while(dcnt && *pt!=(v=flash.write(addr,*pt))) dcnt--; if(v!=*pt) com1 << "pb " << *pt << "!=" << v << "\r\n"; addr++; pt++; } #elif (FLASH_TYPE==FLASH_INTEL) U8 *pt= (U8*)addr,v=0; addr=0x10000-data; while(data--) { dcnt=10; while(dcnt && *pt!=(v=flash.write(addr,*pt))) dcnt--; if(v!=*pt) com1 << "pb " << *pt << "!=" << v << "\r\n"; addr++; pt++; } #endif com1 << "write done\r\n"; } void cmdDiff(U32 *src,U32 *dst,U32 data) { data/=sizeof(U32); while(data--) { if(*src!=*dst) { com1 << '@' << U32(src) << ':' << *src << "!=" << *dst << "\r\n"; break; } src++; dst++; } }