📄 itgate-write-bootloader.c
字号:
// itgate flash bootloader ver1.0 //#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/io.h>/* some defines */#define FALSE 0#define TRUE 1#define LPT_PORT 0x378#define DEFAULT_IO_DELAY 1unsigned char FlashData[0x30000];/* some global vars */unsigned char output_state=0x00;unsigned char last_dbg_reg=0x00;unsigned int io_delay=DEFAULT_IO_DELAY;unsigned int ignore_io_error=TRUE;unsigned char buffer[4*1024];/* JTAG cable i/o access, LPT1 in this case */unsigned char input_byte(unsigned short ioport);void output_byte(unsigned short ioport,unsigned char data);/* JTAG I/O */void halt_target(int state);unsigned char clock_jtag(unsigned int tms,unsigned int tdi);/* JTAG IR I/O */unsigned int rw_ir(unsigned int reg, unsigned int data, unsigned int rw);void write_ir_INS(unsigned int data);unsigned int rw_ir_STATUS(unsigned int data,unsigned int dowrite);unsigned int rw_ir_SPR(unsigned int data,unsigned int rw);/* itgate PPC instructions */void ppc_write_register(unsigned int reg,unsigned int data);unsigned int ppc_read_register(unsigned int reg);void ppc_write32(unsigned int address, unsigned int data);void ppc_write16(unsigned int address, unsigned short data);unsigned short ppc_read16(unsigned int address);void ppc_mtdcr(unsigned int dcr,unsigned int data);void ppc_mtspr(unsigned int spr,unsigned int data);void ppc_mtmsr(unsigned int data);/* misc */void usage(void);/* higher level functions */int target_tests(void);void target_setup(void);void reset_target(void);/************************************************************************************* Main *************************************************************************************/int main(int argc, char* argv[]){ unsigned int t,j; unsigned short mcode,memsize; unsigned short Wait,p; FILE *fin; char FlashName[255]="./root/u-boot-"; /* check arguments */ if (argc==2) { usage(); strcat(FlashName, argv[1]); printf(">> FlashPath = %s\n\n", FlashName); } else { usage(); return 0; } /* ok let's go */ if (ioperm(LPT_PORT,3,1)) { perror("Could not set io permissions. Maybe you should run this tool as root?"); return -1; } printf("*** CPU and JTAG communications check ***\n"); printf("LPT/JTAG IO Delay set to %u\n",io_delay); reset_target(); ignore_io_error=FALSE; if (target_tests()) { printf("Bad flash memory.\n"); return -1; } target_setup(); printf("Hardware setup ok\n"); /* flash memory ID test */ printf("*** Flash check ***\n"); ppc_write16(0x7FC00000,0xF0); ppc_write16(0x7FC00AAA,0xAA); ppc_write16(0x7FC00554,0x55); ppc_write16(0x7FC00AAA,0x90); mcode=ppc_read16(0x7FC00000); printf("manufacturer code: 0x%04x\n",mcode); memsize=ppc_read16(0x7FC00002); printf("memory size code: 0x%04x\n",memsize); if (mcode != 0x01 && memsize != 0x227E) { printf("Flash Memory ID's do not match! (should be 0x01 and 0x227E)\n"); printf("Are you sure this is a Itgate?\n"); printf("I'm out of here anyway...\n"); return -2; } printf("Chip erase 0x7FC00000 "); //chip erase ppc_write16(0x7FC00000,0xF0); ppc_write16(0x7FC00AAA,0xAA); ppc_write16(0x7FC00554,0x55); ppc_write16(0x7FC00AAA,0x80); ppc_write16(0x7FC00AAA,0xAA); ppc_write16(0x7FC00554,0x55); ppc_write16(0x7FC00AAA,0x10); ppc_write16(0x7FC00000,0xF0); Wait=0; p=1; while( (Wait!=0xFFFF) && (p<1000)) { Wait=ppc_read16(0x7FC00000) ; usleep(100000); p++; if((p%10)==0) { printf("."); fflush(stdout); } } printf("\n"); if(p<1000) { printf("Flash bootloader \n"); fin = fopen(FlashName, "r"); if(fin == NULL) { printf("Can not open %s\n", FlashName); return -3; } fseek(fin, 0, SEEK_END); t=ftell(fin); if(t!=0x30000) { printf("Bad file size.\n"); fclose(fin); return -4; } fseek(fin, SEEK_SET, 0); fread(FlashData, 0x30000 , 1, fin); ppc_write16(0x7FC00000,0xF0); ppc_write16(0x7FC00AAA,0xAA); ppc_write16(0x7FC00554,0x55); ppc_write16(0x7FC00AAA,0x20); printf("00%%"); fflush(stdout); for(j=0; j<t; j+=2) { if((j%1000) == 0) { printf("%c%c%c%02d%%",'\b','\b','\b',100*j/t); fflush(stdout); } if((FlashData[j]<<8)+FlashData[j+1] != 0xFFFF ) ppc_write32(0xFFFD0000+j-2,(0xA0<<16)+(FlashData[j]<<8)+FlashData[j+1]); } ppc_write16(0x7FC00000,0x90); ppc_write16(0x7FC00000,0x00); printf("\b\b\b100%% done.\n"); printf("Check flash \n"); printf("00%%"); fflush(stdout); for(j=0; j<t; j+=2) { if((j%1000) == 0) { printf("%c%c%c%02d%%", '\b','\b','\b', 100*j/t); fflush(stdout); } if ( ppc_read16(0xFFFD0000+j)!=((FlashData[j]<<8)+FlashData[j+1])) break; } if(j==t) { printf("\b\b\b100%% done.\n"); printf("\n>>Flash ok.\n"); } else printf("\n>>Flash error.\n"); fclose(fin); } else { printf("Timeout chip erase.\n"); }exit_reset: output_byte(LPT_PORT,0); output_byte(LPT_PORT,1); return 0;}void target_setup(void){ //# initialize chip interconnect register //write cic0_cr 0x10800000 //write cic0_vcr 0x00400000 //write cic0_sel3 0x00000000 ppc_mtdcr(0x30,0x10800000); ppc_mtdcr(0x33,0x000400000); ppc_mtdcr(0x35,0x00000000); //# Turn on DRAM controller ppc_mtdcr(0x9A,0xA0000000); //# Initialize Bank 0 for FLASH ppc_mtdcr(0x70,0); ppc_mtdcr(0x71,0); ppc_mtdcr(0x72,0); ppc_mtdcr(0x73,0); ppc_mtdcr(0x74,0); ppc_mtdcr(0x75,0); ppc_mtdcr(0x76,0); ppc_mtdcr(0x77,0); ppc_mtdcr(0x80,0xF878bffe); ppc_mtdcr(0x81,0xff00bffe); ppc_mtdcr(0x81,0xff00bffe); ppc_mtdcr(0x82,0xff00bffe); ppc_mtdcr(0x83,0xff00bffe); ppc_mtdcr(0x84,0xff00bfff); ppc_mtdcr(0x85,0xff00bfff); ppc_mtdcr(0x86,0xff00bfff); ppc_mtdcr(0x87,0xff00bfff); ppc_mtmsr(0); ppc_mtdcr(0x91,0xffffffff); ppc_mtdcr(0x93,0);}int target_tests(void){ unsigned int result; rw_ir_SPR(0xaa55aa55,TRUE); result = rw_ir_SPR(0,FALSE); if (result != 0xaa55aa55) { printf("ERROR: register test failed\n"); printf("Check your JTAG/LPT1 connection and/or adjust your voltage regulator\n"); return -1; } ppc_write_register(3,0x77887788); ppc_write_register(2,0x55667788); if ((ppc_read_register(3) != 0x77887788) || (ppc_read_register(2) != 0x55667788)) { printf("ERROR: insn/reg2 test failed\n"); printf("Check your JTAG/LPT1 connection and/or adjust your voltage regulator\n"); return -1; } rw_ir_SPR(0x12345678,TRUE); write_ir_INS(0x7c13faa6); rw_ir_SPR(0x1010101,TRUE); write_ir_INS(0x7c33faa6); write_ir_INS(0x7c410214); write_ir_INS(0x7c53fba6); if (rw_ir_SPR(0,FALSE) != 0x13355779) { printf("ERROR: cpu test failed\n"); printf("Are you sure your target is a PowerPC?\n"); return -1; } printf("Your target CPU seems to be a PowerPC indeed. Let's continue...\n"); return 0;}void usage(void){ printf("JTAG Flasher for Itgate\n"); printf("GPL (c) 2006 T-Hydron\n"); printf("Usage:"); printf("itgate-write-bootloader TGS100/TGS110/TGS200/TGS210/TGS220/TGS230/TGS250/...\n\n"); }unsigned char input_byte(unsigned short ioport){ return inb(ioport);}void output_byte(unsigned short ioport,unsigned char data){ outb(data,ioport);}void reset_target(void){ int i; halt_target(1); for(i=0;i<64;i++) clock_jtag(1,0); usleep(100000); rw_ir_STATUS(0xb8000000,TRUE); halt_target(0); usleep(100000); rw_ir_STATUS(0x80000000,TRUE); }void halt_target(int state){ if (state==0) { output_state&=0x0E; } else { output_state|=0xF1; } output_byte(LPT_PORT,output_state);}unsigned char clock_jtag(unsigned int tms,unsigned int tdi){ int i; output_state&=0xF1; if (tms) output_state|=0x02; if (tdi) output_state|=0x08; for(i=0;i<io_delay;i++) output_byte(LPT_PORT,output_state); output_state|=0x04; for(i=0;i<io_delay;i++) output_byte(LPT_PORT,output_state); return (input_byte(LPT_PORT+1) >> 7) ^ 0x01;}unsigned int rw_ir_STATUS(unsigned int data,unsigned int dowrite){ return rw_ir(0x2C,data,dowrite);}void write_ir_INS(unsigned int data){ rw_ir(0x3C,data,TRUE);}unsigned int rw_ir_SPR(unsigned int data,unsigned int dowrite){ return rw_ir(0x5C,data,dowrite);}unsigned int rw_ir(unsigned int reg, unsigned int data, unsigned int dowrite){ unsigned int mask; unsigned int result; int i; clock_jtag(0,0); clock_jtag(1,0); if (last_dbg_reg != reg) { /* load IR */ clock_jtag(1,0); clock_jtag(0,0); clock_jtag(0,0); for(i=0,mask=1;i<7;i++) { clock_jtag((i==6),(reg & mask)); mask<<=1; } clock_jtag(1,0); clock_jtag(1,0); last_dbg_reg = reg; if (last_dbg_reg==0x2C) last_dbg_reg=-1; } /* load DR */ clock_jtag(0,0); clock_jtag(0,0); for(i=0,result=0,mask=1;i<32;i++) { if (clock_jtag(0,(data & mask))) result|=mask; mask<<=1; } if (clock_jtag(1,dowrite) && !ignore_io_error) { printf("ERROR: communication with LPT/JTAG too fast. I think;-)\n"); printf("Just try again. If this error occurred during a write, don't\n"); printf("forget to erase. If you keep getting this error, pass a higher\n"); printf("value for io_delay as parameter.\n"); printf("You can also get this error if you execute this tool to quickly\n"); printf("after powering up your itgate. Give it a second or two.\n"); printf("Exiting...\n"); exit(EXIT_FAILURE); } clock_jtag(1,0); clock_jtag(0,0); return result;}void ppc_write_register(unsigned int reg,unsigned int data){ if (reg > 31) { printf("illegal reg\n"); return; } rw_ir_SPR(data,1); write_ir_INS((reg << 21) | 0x7c13faa6); // mfspr RT,SPRN : SPRN <- SPRF[5:9] || SPRF[0:4] ; (RT) <- (SPR(SPRN)) // 011111 00000 1001111111 0101010011 0 // 31 reg 639 339 - // SPRN <- 1011 ; (reg) <- SPR(SPRN)}unsigned int ppc_read_register(unsigned int reg){ if (reg > 31) { printf("illegal reg\n"); return 0; } write_ir_INS((reg << 21) | 0x7c13fba6); // mtspr SPRN,RT : SPRN <- SPRF[5:9] || SPRF[0:4] ; (SPR(SPRN)) <- (RS) // 011111 00000 1001111111 0111010011 0 // 31 reg 639 467 - // SPRN <- 1011 ; SPR(SPRN) <- (reg) return rw_ir_SPR(0,0);}void ppc_mtdcr(unsigned int dcr,unsigned int data){ unsigned int save,ins; if (dcr > 0x3FF) { printf("illegal dcr\n"); return; } save=ppc_read_register(0); ppc_write_register(0,data); ins = (dcr & 0x1F) << 16; ins |= ((dcr & 0xFFFFFFE0) << 6); ins |= 0x7c000386; write_ir_INS(ins); // mtdcr DCRN,RS : DCRN <- DCRF[5:9] || DCRF[0:4] ; (DCR(DCRN)) <- (RS) // 011111 00000 0000000000 0111000011 0 // 31 reg dcr 451 - // DCRN <- "swapped dcr" ; DCR(DCRN) <- (reg) ppc_write_register(0,save);}void ppc_write32(unsigned int address, unsigned int data){ ppc_write_register(1,address); ppc_write_register(2,data); write_ir_INS(0x90410000); // stw RS,D(RA) : EA <- (RA|0) + EXTS(D) ; MS(EA,4) <- (RS) // 100100 00010 00001 0000000000000000 // 36 R2 R1 0 // stw R2,0(R1) : EA <- (R1) ; MS(EA,4) <- (RS)}void ppc_mtspr(unsigned int spr,unsigned int data){ unsigned int save,ins; if (spr > 0x3FF) { printf("illegal spr\n"); return; } save=ppc_read_register(0); ppc_write_register(0,data); ins = (spr & 0x1F) << 16; ins |= ((spr & 0xFFFFFFE0) << 6); ins |= 0x7c0003a6; write_ir_INS(ins); // mtspr SPRN,RS : SPRN <- SPRF[5:9] || SPRF[0:4] ; (DCR(DCRN)) <- (RS) // 011111 00000 0000000000 0111000011 0 // 31 reg dcr 451 - // DCRN <- "swapped dcr" ; DCR(DCRN) <- (reg) ppc_write_register(0,save);}void ppc_mtmsr(unsigned int data){ unsigned int save; save=ppc_read_register(0); ppc_write_register(0,data); write_ir_INS(0x7c000124); // mtmsr RS : (MSR) <- (RS) // 011111 00000 0000000000 0010010010 0 // 31 R0 - 146 - // (MSR) <- (R0) ppc_write_register(0,save);}void ppc_write16(unsigned int address, unsigned short data){ ppc_write_register(1,address); ppc_write_register(2,data); write_ir_INS(0xb0410000); // sth RS,D(RA) : EA <- (RA|0) + EXTS(D) ; MS(EA,2) <- (RS)[16:31] // 101100 00010 00001 0000000000000000 // 44 R2 R1 0 // sth R2,0(R1) : EA <- (R1) ; MS(EA,2) <- (RS)[16:31]}unsigned short ppc_read16(unsigned int address){ ppc_write_register(1,address); write_ir_INS(0xa0210000); // lhz RT,D(RA) : EA <- (RA|0) + EXTS(D) ; (RT) <- 0x0000 || MS(EA,2) // 101000 00001 00001 0000000000000000 // 40 R1 R1 0 // lhz R1,0(R1) : EA <- (R1) ; (R1) <- 0x0000 || MS(EA,2) return (unsigned short)ppc_read_register(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -