You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

138 lines
2.9 KiB

#!/usr/bin/perl
my ($myedata,$myend,$initmips,$mystart);
open(F,qq(objdump -x $ARGV[0]|));
while(<F>)
{
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<<y))
#define WAY(x) WAY_(x,WAYBIT)
asm volatile(\
" .set mips3;\\n" \\
" li \$5,0x80000000;\\n" \\
" addu \$6,\$5,16384;\\n" \\
"1:\\n" \\
" cache 1," WAY(0) "(\$5);\\n" \\
" cache 1," WAY(1) "(\$5);\\n" \\
" cache 1," WAY(2) "(\$5);\\n" \\
" cache 1," WAY(3) "(\$5);\\n" \\
" cache 0," WAY(0) "(\$5);\\n" \\
" cache 0," WAY(1) "(\$5);\\n" \\
" cache 0," WAY(2) "(\$5);\\n" \\
" cache 0," WAY(3) "(\$5);\\n" \\
" add \$5,\$5,32;\\n" \\
" bne \$5,\$6,1b;\\n" \\
" nop;\\n" \\
" .set mips0;\\n" \\
::: "\$5","\$6");
}
#endif
void initmips(unsigned int msize,int dmsize,int dctrl)
{
long *edata=(void *)$myedata;
long *end=(void *)$myend;
long *p;
int debug=(msize==0);
CPU_TLBClear();
stringserial("Uncompressing Bios");
if(!debug||dctrl&1)enable_cache();
while(1)
{
if(run_unzip(biosdata,$mystart)>=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
);