initial version
[otheros_bootloader.git] / otheros_bootloader_loader.S
blob1842f7911789892d87f86198ef3dc899c1c523f6
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; version 2 of the License.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  */
17 .set STACK_SIZE,                                                        0x100
18 .set STACK_LR,                                                          (STACK_SIZE + 0x10)
19 .set STACK_R25,                                                         (STACK_SIZE - 1 * 0x8)
20 .set STACK_R26,                                                         (STACK_SIZE - 2 * 0x8)
21 .set STACK_R27,                                                         (STACK_SIZE - 3 * 0x8)
22 .set STACK_R28,                                                         (STACK_SIZE - 4 * 0x8)
23 .set STACK_R29,                                                         (STACK_SIZE - 5 * 0x8)
24 .set STACK_R30,                                                         (STACK_SIZE - 6 * 0x8)
25 .set STACK_R31,                                                         (STACK_SIZE - 7 * 0x8)
26 .set STACK_LPAR_MEM,                                            (STACK_SIZE - 8 * 0x8)
28 .set SUB_SLL_LOAD_LV2,                                          0x80000E44              /* sll_load_lv2 */
29 .set SUB_MMAP_LPAR_MEM,                                         0x800026B4
30 .set SUB_OPEN,                                                          0x80013D40              /* syscall 0x7 */
31 .set SUB_CLOSE,                                                         0x80013D7C              /* syscall 0x8 */
32 .set SUB_READ,                                                          0x80013DB8              /* syscall 0x9 */
33 .set SUB_MUNMAP,                                                        0x80013EB8              /* syscall 0x19 */
34 .set SUB_BSET,                                                          0x80000278
35 .set SUB_BCOPY,                                                         0x80000254
37 #define BL(sub_addr)                                            \
38         li %r30, 0;                                                             \
39         oris %r30, %r30, (sub_addr >> 16);              \
40         ori %r30, %r30, (sub_addr & 0xFFFF);    \
41         mtctr %r30;                                                             \
42         bctrl
44 .set CACHE_LINE_SIZE,                                           0x80
46 .set FD_ERROR,                                                          0x10
47 .set HEADER_ERROR,                                                      0x14
49 #define LWZ_DATA(reg, data_addr)                        lwz reg, data_addr(%r31)
50 #define LD_DATA(reg, data_addr)                         ld reg, data_addr(%r31)
51 #define LD_DATA_PTR(reg, data_addr)                     addi reg, %r31, data_addr - sll_load_lv2
54  * %r3 - path
55  * %r4 - laid
56  * %r5 - lpar id
57  *
58  * %r25 - volatile
59  * %r26 - OtherOS bootloader load address
60  * %r27 - return value
61  * %r28 - size of /dev/rflash_lx
62  * %r29 - file descriptor of /dev/rflash_lx
63  * %r30 - reserved for function calls
64  * %r31 - reserved for data accesses
65  */
66 .globl sll_load_lv2
67 sll_load_lv2:
69         stdu %r1, -STACK_SIZE(%r1)
70         mflr %r0
71         std %r0, STACK_LR(%r1)
72         std %r25, STACK_R25(%r1)
73         std %r26, STACK_R26(%r1)
74         std %r27, STACK_R27(%r1)
75         std %r28, STACK_R28(%r1)
76         std %r29, STACK_R29(%r1)
77         std %r30, STACK_R30(%r1)
78         std %r31, STACK_R31(%r1)
80         bl 1f
84         mflr %r31
85         addi %r31, %r31, (sll_load_lv2 - 1b)
87         /* map lpar memory */
89         mr %r3, %r5
90         li %r4, 0
91         LD_DATA(%r26, bootloader_load_addr)
92         LD_DATA(%r28, dev_rflash_lx_size)
93         add %r5, %r26, %r28
94         addi %r6, %r1, STACK_LPAR_MEM
95         BL(SUB_MMAP_LPAR_MEM)
96         cmpwi %cr7, %r3, 0
97         mr %r27, %r3
98         bne %cr7, done
100         /* zero out lpar memory */
102         ld %r3, STACK_LPAR_MEM(%r1)
103         li %r4, 0
104         mr %r5, %r28
105         BL(SUB_BSET)
107         /* open /dev/rflash_lx where OtherOS bootloader is stored */
109         LD_DATA_PTR(%r3, dev_rflash_lx)
110         li %r4, 0
111         li %r27, FD_ERROR
112         BL(SUB_OPEN)
113         cmpwi %cr7, %r3, 0
114         mr %r29, %r3
115         blt %cr7, bad1
117         /* read header */
119         extsw %r3, %r29
120         ld %r4, STACK_LPAR_MEM(%r1)
121         LD_DATA(%r25, header_size)
122         mr %r5, %r25
123         li %r27, FD_ERROR
124         BL(SUB_READ)
125         cmpd %cr7, %r3, %r25
126         bne %cr7, bad2
128         /* check header magic */
130         li %r27, HEADER_ERROR
132         LD_DATA(%r3, header_magic)
133         ld %r5, STACK_LPAR_MEM(%r1)
134         ld %r4, 0(%r5)
135         cmpd %cr7, %r3, %r4
136         bne %cr7, bad2
138         /* read OtherOS bootloader size from header */
140         ld %r25, 8(%r5)
141         cmpd %cr7, %r25, %r28
142         bgt %cr7, bad2
144         /* read OtherOS bootloader to lpar memory */
146         extsw %r3, %r29
147         ld %r4, STACK_LPAR_MEM(%r1)
148         mr %r5, %r25
149         li %r27, FD_ERROR
150         BL(SUB_READ)
151         cmpd %cr7, %r3, %r25
152         bne %cr7, bad2
154         /* flush data cache */
156         li %r9, 0
157         b 2f
161         ld %r0, STACK_LPAR_MEM(%r1)
162         add %r0, %r9, %r0
163         dcbst %r0, %r0
164         addi %r9, %r9, CACHE_LINE_SIZE
168         cmpd %cr7, %r9, %r28
169         blt %cr7, 1b
171         sync
173         /* flush code cache */
175         li %r9, 0
176         b 2f
180         ld %r0, STACK_LPAR_MEM(%r1)
181         add %r0, %r9, %r0
182         icbi %r0, %r0
183         addi %r9, %r9, CACHE_LINE_SIZE
187         cmpd %cr7, %r9, %r28
188         blt %cr7, 1b
190         isync
192 success:
194         li %r27, 0
196 bad2:
198         /* close /dev/rflash_lx */
200         extsw %r3, %r29
201         BL(SUB_CLOSE)
203 bad1:
205         /* unmap lpar memory */
207         ld %r3, STACK_LPAR_MEM(%r1)
208         add %r4, %r26, %r28
209         BL(SUB_MUNMAP)
211 done:
213         rldicl %r3, %r27, 0, 32
215         ld %r0, STACK_LR(%r1)
216         ld %r25, STACK_R25(%r1)
217         ld %r26, STACK_R26(%r1)
218         ld %r27, STACK_R27(%r1)
219         ld %r28, STACK_R28(%r1)
220         ld %r29, STACK_R29(%r1)
221         ld %r30, STACK_R30(%r1)
222         ld %r31, STACK_R31(%r1)
223         addi %r1, %r1, STACK_SIZE
224         mtlr %r0
225         blr
227 /* read-only data */
229 data_start:
231 bootloader_load_addr:
232         .quad 0x0000000000000000
234 header_size:
235         .quad (2 * 0x200) /* 2 sectors of size 0x200 */
237 header_magic:
238         .quad 0x0FACE0FFDEADBABE
240 dev_rflash_lx_size:
241         .quad (0x4000 * 0x200) /* 0x4000 sectors of size 0x200 */
243 dev_rflash_lx:
244         .asciz "/dev/rflash_lx"
246 data_end: