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.
 
 
 
 
 
 

141 lines
2.6 KiB

#!/usr/bin/perl
my ($myedata,$myend,$initmips,$mystart,$tgt_putchar);
open(F,qq(mips-elf-objdump -x $ARGV[0]|));
while(<F>)
{
chomp;
if(/f{8}(\w+).+_edata/){
$myedata=qq(0x$1);
}
if(/f{8}(\w+).+_end$/){
$myend=qq(0x$1);
}
if(/f{8}(\w+).+initmips$/){
$myinitmips=qq(0x$1);
}
if(/f{8}(\w+).+\s_start$/){
$mystart=qq(0x$1);
}
if(/f{8}(\w+).+\stgt_putchar$/){
$tgt_putchar=qq(0x$1);
}
}
printf(<< "END"
typedef long long off_t;
struct callvectors {
int (*open) (char *, int, int);
int (*close) (int);
int (*read) (int, void *, int);
int (*write) (int, void *, int);
off_t (*lseek) (int, off_t, int);
int (*printf) (const char *, ...);
void (*cacheflush) (void);
char *(*gets) (char *);
};
struct callvectors *cvs;
void realinitmips(unsigned int msize);
#ifndef NOCACHE2
void flush_cache2()
{
asm volatile("
mfc0 \$3, \$15 # read processor ID register
li \$2, 0x6303 #godson2f prid
beq \$2, \$3, godson_2f
nop
li \$2, 0x6302 #godson2e prid
bne \$2, \$3,11f
nop
# godson2e
godson_2f:
li \$2, 0x80000000
addu \$3,\$2,512*1024
10:
cache 3, 0(\$2)
cache 3, 1(\$2)
cache 3, 2(\$2)
cache 3, 3(\$2)
addu \$2, 32
bne \$2,\$3, 10b
nop
11:
"
::
:"\$2","\$3"
);
}
#else
void flush_cache()
{
asm volatile("
.set mips3;
li \$5,0x80000000
addu \$6,\$5,16384
1:
cache 1,0(\$5)
cache 1,1(\$5)
cache 1,2(\$5)
cache 1,3(\$5)
cache 0,(\$5)
add \$5,\$5,32
bne \$5,\$6,1b
nop
.set mips0;
"
::
: "\$5","\$6");
}
#endif
void initmips(unsigned int msize,struct callvectors *cv)
{
long *edata=(void *)$myedata;
long *end=(void *)$myend;
long *p;
cvs=cv;
stringserial("Uncompressing Bios");
run_unzip(biosdata,$mystart);
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
// cv->cacheflush();
stringserial("flush_cache...");
#ifdef NOCACHE2
flush_cache();
#else
flush_cache2();
#endif
stringserial("done,boot now\r\n");
realinitmips(msize);
}
void realinitmips(unsigned int msize)
{
asm ("li \$29,$mystart-0x4000;
li \$2,$myinitmips;
move \$4,\%0;
jalr \$2;
nop;
1: b 1b;nop;"
:
: "r" (msize)
: "\$29", "\$2","\$4");
}
static void (*rom_putchar)(char c)=(${tgt_putchar}-${mystart}+0xbfc00000);
void tgt_putchar(char c)
{
#ifndef NOMSG
cvs->printf("%%c",c);
#endif
}
void stringserial(char *str)
{
#ifndef NOMSG
cvs->printf("%%s",str);
#endif
}
END
);