Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * 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 *)
{
}