1 /*
2 * mips reboot trampoline code
3 */
4 #include "u.h"
5 #include "../port/lib.h"
6 #include "mem.h"
7 #include "dat.h"
8 #include "fns.h"
9 #include "io.h"
10
11 #define csr8r(r) (((ulong *)PHYSCONS)[r])
12 #define csr8o(r, v) (((ulong *)PHYSCONS)[r] = (v))
13
14 enum { /* i8250 registers */
15 Thr = 0, /* Transmitter Holding (WO) */
16 Lsr = 5, /* Line Status */
17 };
18 enum { /* Lsr */
19 Thre = 0x20, /* Thr Empty */
20 };
21
22 void putc(int);
23 void next_kernel(void *, ulong, char **, char **, ulong);
24
25 /*
26 * Copy the new kernel to its correct location in memory,
27 * flush caches, ignore TLBs (we're in KSEG0 space), and jump to
28 * the start of the kernel. Argument addresses are virtual (KSEG0).
29 */
30 void
main(Rbconf * rbconf,ulong aentry,ulong acode,ulong asize)31 main(Rbconf *rbconf, ulong aentry, ulong acode, ulong asize)
32 {
33 static ulong entry, code, size, argc;
34 static char **argv;
35
36 putc('B'); putc('o');
37 /* copy args to heap before moving stack to before a.out header */
38 argv = (char **)rbconf;
39 entry = aentry;
40 code = acode;
41 size = asize;
42 setsp(entry-0x20-4);
43 putc('o');
44
45 memmove((void *)entry, (void *)code, size);
46 putc('t');
47 cleancache();
48 coherence();
49 putc(' ');
50
51 /*
52 * jump to new kernel's entry point.
53 * pass routerboot arg vector in R4-R5.
54 * off we go - never to return.
55 */
56 next_kernel((void*)entry, 4, argv, 0, 0);
57
58 putc('?');
59 putc('!');
60 for(;;)
61 ;
62 }
63
64 void
putc(int c)65 putc(int c)
66 {
67 int i;
68
69 for(i = 0; !(csr8r(Lsr) & Thre) && i < 1000000; i++)
70 ;
71 csr8o(Thr, (uchar)c);
72 for(i = 0; !(csr8r(Lsr) & Thre) && i < 1000000; i++)
73 ;
74 }
75
76 long
syscall(Ureg *)77 syscall(Ureg*)
78 {
79 return -1;
80 }
81
82 void
trap(Ureg *)83 trap(Ureg *)
84 {
85 }
86