1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* mips-setup-simple.S - code to execute before kernel to handle command line
* Copyright (C) 2007 Francesco Chiechi, Alessandro Rubini
* Copyright (C) 2007 Tvblob s.r.l.
*
* derived from Albert Herranz idea (ppc) adding command line support
* (boot_notes structure)
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
/*
* Only suitable for platforms booting with MMU turned off.
* -- Albert Herranz
*/
#include "regdef.h"
/* returns t0 = relocated address of sym */
/* modifies t1 t2 */
/* sym must not be global or this will not work (at least AFAIK up to now) */
#define RELOC_SYM(sym) \
move t0,ra; /* save ra */ \
bal 1f; \
1: \
move t1,ra; /* now t1 is 1b (where we are now) */ \
move ra,t0; /* restore ra */ \
lui t2,%hi(1b); \
ori t2,t2,%lo(1b); \
lui t0,%hi(sym); \
ori t0,t0,%lo(sym); \
sub t0,t0,t2; /* t0 = offset between sym and 1b */ \
add t0,t1,t0; /* t0 = actual address in memory */
.data
.globl setup_simple_start
setup_simple_start:
/* should perform here any required setup */
/* Initialize GOT pointer (verify if needed) */
bal 1f
nop
.word _GLOBAL_OFFSET_TABLE_
1:
move gp, ra
lw t1, 0(ra)
move gp, t1
/* spr8 relocation */
RELOC_SYM(spr8)
move t4,t0 // save pointer to kernel start addr
lw t3,0(t0) // save kernel start address
/* spr9 relocation */
RELOC_SYM(spr9)
lw a0,0(t0) // load argc
// this code is to be changed if boot_notes struct changes
lw t2,12(t4) // t2 is size of boot_notes struct
addi t2,t2,3
srl t2,t2,2
sll v1,t2,2 // v1 = size of boot_notes struct
// aligned to word boundary
addi t0,t4,0x20 // t0 contains the address of "kexec" string
add v0,t4,v1 // v0 points to last word of boot_notes
addi v0,v0,8 // v0 points to address after boot_notes
sw t0,0(v0) // store pointer to "kexec" string there
lw t2,-8(t0) // t2 is size of "kexec" string in bytes
addi t2,t2,3
srl t2,t2,2
sll v1,t2,2 // v1 = size of "kexec" string
// aligned to word boundary
add t2,t0,v1
addi t0,t2,4 // t0 points to size of version string
lw t2,0(t0) // t2 is size of version string in bytes
addi t2,t2,3
srl t2,t2,2
sll v1,t2,2 // v1 = size of version string
// aligned to word boundary
addi t0,t0,8 // t0 points to version string
add t0,t0,v1 // t0 points to start of command_line record
addi t0,t0,12 // t0 points command line
sw t0,4(v0) // store pointer to command line
move a1,v0 // load argv
li a2,0
li a3,0
jr t3
nop
.balign 4
.globl setup_simple_regs
setup_simple_regs:
spr8: .long 0x00000000
spr9: .long 0x00000000
setup_simple_end:
.globl setup_simple_size
setup_simple_size:
.long setup_simple_end - setup_simple_start
|