/*
* mips reboot trampoline code
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#define csr8r(r) (((ulong *)PHYSCONS)[r])
#define csr8o(r, v) (((ulong *)PHYSCONS)[r] = (v))
enum { /* i8250 registers */
Thr = 0, /* Transmitter Holding (WO) */
Lsr = 5, /* Line Status */
};
enum { /* Lsr */
Thre = 0x20, /* Thr Empty */
};
void putc(int);
/*
* Copy the new kernel to its correct location in physical memory,
* flush caches, ignore TLBs (we're in KSEG0 space), and jump to
* the start of the kernel.
*/
void
main(ulong aentry, ulong acode, ulong asize)
{
void (*kernel)(void);
static ulong entry, code, size;
putc('B'); putc('o'); putc('o'); putc('t');
/* copy args to heap before moving stack to before a.out header */
entry = aentry;
code = acode;
size = asize;
setsp(entry-0x20-4);
memmove((void *)entry, (void *)code, size);
cleancache();
coherence();
/*
* jump to kernel entry point.
*/
putc(' ');
kernel = (void*)entry;
(*kernel)(); /* off we go - never to return */
putc('?');
putc('!');
for(;;)
;
}
void
putc(int c)
{
int i;
for(i = 0; !(csr8r(Lsr) & Thre) && i < 1000000; i++)
;
csr8o(Thr, (uchar)c);
for(i = 0; !(csr8r(Lsr) & Thre) && i < 1000000; i++)
;
}
long
syscall(Ureg*)
{
return -1;
}
void
trap(Ureg *)
{
}
|