#!/usr/bin/perl my ($myedata,$myend,$initmips,$mystart); open(F,qq(objdump -x $ARGV[0]|)); while() { chomp; if(/([0-9a-f]+).+_edata/){ $myedata=qq(0x$1); } if(/([0-9a-f]+).+_end$/){ $myend=qq(0x$1); } if(/([0-9a-f]+).+initmips$/){ $myinitmips=qq(0x$1); } if(/([0-9a-f]+).+\s_start$/){ $mystart=qq(0x$1); } } printf(<< "END" void stringserial(char *msg); void realinitmips(unsigned int msize); void enable_cache() { __asm__ volatile( ".set mips2;\\n" \\ " mfc0 \$4,\$16;\\n" \\ " and \$4,\$4,0xfffffff8;\\n" \\ " or \$4,\$4,0x3;\\n" \\ " mtc0 \$4,\$16;\\n" \\ " .set mips0;\\n" :: :"\$4" ); } #ifndef NOCACHE2 void flush_cache2() { asm volatile(\ " mfc0 \$3, \$15; # read processor ID register;\\n" \\ " li \$2, 0x6303; #godson2f prid;\\n" \\ " beq \$2, \$3, godson_2f;\\n" \\ " nop;\\n" \\ " li \$2, 0x6302; #godson2e prid;\\n" \\ " bne \$2, \$3,11f ;\\n" \\ " nop;\\n" \\ "# godson2e;\\n" \\ " godson_2f: " \\ " li \$2, 0x80000000;\\n" \\ " addu \$3,\$2,512*1024;\\n" \\ "10:\\n" \\ " cache 3, 0(\$2);\\n" \\ " cache 3, 1(\$2);\\n" \\ " cache 3, 2(\$2);\\n" \\ " cache 3, 3(\$2);\\n" \\ " addu \$2, 32;\\n" \\ " bne \$2,\$3, 10b;\\n" \\ " nop;\\n" \\ "11:\\n" \\ :::"\$2","\$3" ); } #else void flush_cache() { #ifndef WAYBIT #define WAYBIT 0 #endif #define WAY__(x) #x #define WAY_(x,y) WAY__((x<=0)break; } stringserial("OK,Booting Bios\\r\\n"); for(p=edata;p<=end;p++) { *p=0; } memset($mystart-0x1000,0,0x1000);//$mystart-0x1000 for frame(registers),memset for pretty #ifdef NOCACHE2 flush_cache(); #else flush_cache2(); #endif realinitmips(debug?dmsize:msize); } void realinitmips(unsigned int msize) { asm ("li \$29,$mystart-0x4000;\\n" \\ " li \$2,$myinitmips;\\n" \\ " move \$4,\%0;\\n" \\ " mtc0 \$2,\$24;\\n" \\ " .word 0x4200001f;\\n" \\ " nop;\\n" \\ " 1: b 1b;nop;\\n" \\ : : "r" (msize) : "\$29", "\$2","\$4"); } END );