-
Notifications
You must be signed in to change notification settings - Fork 0
/
0003-Excito-B2-UBoot-workaround.patch
278 lines (278 loc) · 7.84 KB
/
0003-Excito-B2-UBoot-workaround.patch
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
--- /dev/null
+++ arch/powerpc/boot/reloc_shim_itb.S
@@ -0,0 +1,93 @@
+/*
+ This shim is used to move the kernel and device tree
+ blob (DTB) in memory, so that they can boot successfully
+ on an Excito B2 miniserver with the default U-Boot
+ environment, when booting with the rear button pressed
+ (which uses a flattened image tree).
+
+ It copies the DTB from its current location (passed in r3)
+ to the 15MiB boundary, fixes up r3 so it points to the new
+ DTB address, and then copies the kernel itself (whose
+ uncompressed code is inlined after the shim) to the required
+ 0MiB boundary, and then jumps to it.
+
+ The kernel will of course reclaim all the additional memory
+ used, on startup.
+
+ None of the registers used to pass information into the
+ kernel by U-Boot are affected by this shim (other than r3).
+
+ Copyright (c) 2015 sakaki <sakaki@deciban.com>
+ License: GPL 3.0+
+ NO WARRANTY
+*/
+ .machine ppc
+ .text
+ .align 2
+ .p2align 4,,15
+ .globl _main
+ .set dtbdst, 0x00f00000 # move DTB to 15MiB
+ .set kerneldst, 0x00000000 # move kernel to 0MiB
+ .set kernelsrcoffset, kernel_start-marker
+ # short offset to kernel
+ # start location
+ .set kernellen, kernel_end-kernel_start
+ # length of kernel image
+ .set wordlen, 0x04 # word = 32 bits = 4 bytes
+ .set dtblenoff, 0x04 # length is second word in
+ # DTB
+_main:
+/*
+ first, relocate the (modified & already moved by U-Boot) DTB to
+ dtbdst (current ptr in r3); it will be safe there
+ from being overwritten
+ then modify r3, so it points to the new location
+*/
+ la r16, 0(r3) # set src to passed DTB ptr
+ addis r17, 0, dtbdst@h # set dst to 15MiB boundary
+ ori r17, r17, dtbdst@l
+ lwz r18, dtblenoff(r3) # set len of passed DTB
+ la r3, 0(r17) # patch r3 pointer to new loc
+ bl copy_mem # do copy
+
+/* next, move the kernel itself */
+ bl marker # store &marker in link reg
+marker:
+ mflr r16 # move to copy_mem's src ptr
+ addi r16, r16, kernelsrcoffset # add offset, so r16 now points
+ # to absolute address of
+ # kernel_start
+ addis r17, 0, kerneldst@h # set dst to 0MiB boundary
+ ori r17, r17, kerneldst@l
+ addis r18, 0, kernellen@h # setup kernel length
+ ori r18, r18, kernellen@l
+ bl copy_mem # do copy
+
+/* copy complete - pass control to kernel */
+ addis r20, 0, kerneldst@h # kernel target ptr
+ ori r20, r20, kerneldst@l
+ mtlr r20
+ blr # ikinasai!
+
+copy_mem:
+/*
+ subroutine: on entry, source address should be in r16,
+ destination in r17, and length in r18; return address
+ should be in lr
+ on exit, r18 will be next usable destination address (word
+ aligned); r16/r17/r19 overwritten; no stack is used
+*/
+ add r18, r18, r17 # r18 := first non-dst addr
+copy_next_word:
+ lwz r19, 0(r16) # load 4 bytes from src...
+ stw r19, 0(r17) # and save them to dst
+ addi r16, r16, wordlen # inc source
+ addi r17, r17, wordlen # inc dest
+ cmpl 0, 0, r17, r18 # compare with fencepost
+ blt copy_next_word # if < fence, keep going
+ blr # return
+
+ .align 2
+kernel_start:
+ .incbin "../../../vmlinux.bin" # inline a copy of the kernel
+kernel_end:
--- /dev/null
+++ arch/powerpc/boot/reloc_shim_r1.its
@@ -0,0 +1,46 @@
+/*
+ * U-Boot flattened image tree source file, with kernel and DTB
+ * for use with the relocation shim
+ */
+
+/dts-v1/;
+
+/ {
+ description = "Excito B2 Gentoo Image with Kernel and DTB";
+ #address-cells = <1>;
+ images {
+ kernel@1 {
+ description = "Shimmed KERNNAME";
+ data = /incbin/("./reloc_shim_vmlinux.bin");
+ type = "kernel";
+ arch = "powerpc";
+ os = "linux";
+ compression = "none";
+ load = <0x02000000>;
+ entry = <0x02000000>;
+ hash@1 {
+ algo = "sha1";
+ };
+ };
+
+ fdt@1 {
+ description = "Flattened Device Tree Blob for B2 (rev 1)";
+ data = /incbin/("./bubba.dtb");
+ type = "flat_dt";
+ arch = "powerpc";
+ compression = "none";
+ hash@1 {
+ algo = "sha1";
+ };
+ };
+ };
+
+ configurations {
+ default = "config@1";
+ config@1 {
+ description = "Boot Excito B2 with Supplied Kernel and DTB";
+ kernel = "kernel@1";
+ fdt = "fdt@1";
+ };
+ };
+};
--- /dev/null
+++ arch/powerpc/boot/reloc_shim_r2.its
@@ -0,0 +1,46 @@
+/*
+ * U-Boot flattened image tree source file, with kernel and DTB
+ * for use with the relocation shim
+ */
+
+/dts-v1/;
+
+/ {
+ description = "Excito B2 Gentoo Image with Kernel and DTB";
+ #address-cells = <1>;
+ images {
+ kernel@1 {
+ description = "Shimmed KERNNAME";
+ data = /incbin/("./reloc_shim_vmlinux.bin");
+ type = "kernel";
+ arch = "powerpc";
+ os = "linux";
+ compression = "none";
+ load = <0x02000000>;
+ entry = <0x02000000>;
+ hash@1 {
+ algo = "sha1";
+ };
+ };
+
+ fdt@1 {
+ description = "Flattened Device Tree Blob for B2 (rev2)";
+ data = /incbin/("./8313E21.dtb");
+ type = "flat_dt";
+ arch = "powerpc";
+ compression = "none";
+ hash@1 {
+ algo = "sha1";
+ };
+ };
+ };
+
+ configurations {
+ default = "config@1";
+ config@1 {
+ description = "Boot Excito B2 with Supplied Kernel and DTB";
+ kernel = "kernel@1";
+ fdt = "fdt@1";
+ };
+ };
+};
--- /dev/null
+++ arch/powerpc/boot/reloc_shim.S
@@ -0,0 +1,81 @@
+/*
+ This shim is used to move the kernel and device tree
+ blob (DTB) in memory, so that they can boot successfully
+ on an Excito B2 miniserver with the default U-Boot
+ environment.
+
+ It copies the DTB from its current location (passed in r3)
+ to the 15MiB boundary, fixes up r3 so it points to the new
+ DTB address, and then copies the kernel itself (whose
+ length is at the 16MiB boundary, and whose code starts 4 bytes
+ thereafter) to the required 0MiB boundary, and then jumps to it.
+
+ The kernel will of course reclaim all the additional memory
+ used, on startup.
+
+ None of the registers used to pass information into the
+ kernel by U-Boot are affected by this shim (other than r3).
+
+ Copyright (c) 2015 sakaki <sakaki@deciban.com>
+ License: GPL 3.0+
+ NO WARRANTY
+*/
+
+ .machine ppc
+ .text
+ .align 2
+ .p2align 4,,15
+ .globl _main
+ .set dtbdst, 0x00f00000 # move DTB to 15MiB
+ .set kerneldst, 0x00000000 # move kernel to 0MiB
+ .set kernellen, 0x01000000 # kernel length at 16MiB
+ .set kernelsrc, 0x01000004 # kernel starts 1 word later
+ .set wordlen, 0x04 # word = 32 bits = 4 bytes
+ .set dtblenoff, 0x04 # length is second word in
+ # DTB
+_main:
+/*
+ first, relocate the (modified & already moved by U-Boot) DTB to
+ dtbdst (current ptr in r3); it will be safe there
+ from being overwritten
+ then modify r3, so it points to the new location
+*/
+ la r16, 0(r3) # set src to passed DTB ptr
+ addis r17, 0, dtbdst@h # set dst to 15MiB boundary
+ ori r17, r17, dtbdst@l
+ lwz r18, dtblenoff(r3) # set len of passed DTB
+ la r3, 0(r17) # patch r3 pointer to new loc
+ bl copy_mem # do copy
+
+/* next, move the kernel itself */
+ addis r16, 0, kernellen@h # set src to 16MiB boundary
+ ori r16, r16, kernellen@l # (this holds kernel len)
+ addis r17, 0, kerneldst@h # set dst to 0MiB boundary
+ ori r17, r17, kerneldst@l
+ lwz r18, 0(r16) # set len of kernel
+ addi r16, r16, wordlen # move ptr to kernel proper
+ bl copy_mem # do copy
+
+/* copy complete - pass control to kernel */
+ addis r20, 0, kerneldst@h # kernel target ptr
+ ori r20, r20, kerneldst@l
+ mtlr r20
+ blr # ikinasai!
+
+copy_mem:
+/*
+ subroutine: on entry, source address should be in r16,
+ destination in r17, and length in r18; return address
+ should be in lr
+ on exit, r18 will be next usable destination address (word
+ aligned); r16/r17/r19 overwritten; no stack is used
+*/
+ add r18, r18, r17 # r18 := first non-dst addr
+copy_next_word:
+ lwz r19, 0(r16) # load 4 bytes from src...
+ stw r19, 0(r17) # and save them to dst
+ addi r16, r16, wordlen # inc source
+ addi r17, r17, wordlen # inc dest
+ cmpl 0, 0, r17, r18 # compare with fencepost
+ blt copy_next_word # if < fence, keep going
+ blr # return