tizen 2.3.1 release
[external/qemu.git] / roms / openbios / arch / ppc / qemu / start.S
1 /*
2  *   Creation Date: <2001/06/16 21:30:18 samuel>
3  *   Time-stamp: <2003/04/04 16:32:06 samuel>
4  *
5  *      <init.S>
6  *
7  *      Asm glue for ELF images
8  *
9  *   Copyright (C) 2001, 2002, 2003 Samuel Rydh (samuel@ibrium.se)
10  *
11  *   This program is free software; you can redistribute it and/or
12  *   modify it under the terms of the GNU General Public License
13  *   as published by the Free Software Foundation
14  *
15  */
16
17 #include "autoconf.h"
18 #include "asm/asmdefs.h"
19 #include "asm/processor.h"
20
21 /************************************************************************/
22 /*      Macros                                                          */
23 /************************************************************************/
24
25 #define ILLEGAL_VECTOR( v )     .org __vectors + v ; vector__##v: bl trap_error ;
26 #define VECTOR( v, dummystr )   .org __vectors + v ; vector__##v
27
28 #ifdef CONFIG_PPC_64BITSUPPORT
29
30 /* We're trying to use the same code for the ppc32 and ppc64 handlers here.
31  * On ppc32 we only save/restore the registers, C considers volatile.
32  *
33  * On ppc64 on the other hand, we have to save/restore all registers, because
34  * all OF code is 32 bits, which only saves/restores the low 32 bits of the
35  * registers it clobbers.
36  */
37
38 #define EXCEPTION_PREAMBLE_TEMPLATE \
39         mtsprg1 r1 ;                            /* scratch */ \
40         mfcr    r1 ; \
41         mtsprg2 r1 ;                            /* scratch */ \
42         lis     r1, 0x8000 ;                    /* r1=0x80000000 */ \
43         add.    r1,r1,r1 ;                      /* r1=r1+r1 (high 32bit !0) */ \
44         beq     1f; \
45         \
46         mfmsr   r1 ;                            /* unset MSR_SF */ \
47         clrldi  r1,r1,1 ; \
48         mtmsrd  r1 ; \
49 1: \
50         mfsprg0 r1 ;                            /* exception stack in sprg0 */ \
51 .ifc ULONG_SIZE, 8 ; \
52         addi    r1,r1,-(40 * ULONG_SIZE) ;      /* push exception frame */ \
53 .else ; \
54         addi    r1,r1,-(20 * ULONG_SIZE) ;      /* push exception frame */ \
55 .endif ; \
56  \
57         stl     r0,(0 * ULONG_SIZE)(r1) ;       /* save r0 */ \
58         mfsprg1 r0 ; \
59         stl     r0,(1 * ULONG_SIZE)(r1) ;       /* save r1 */ \
60         stl     r2,(2 * ULONG_SIZE)(r1) ;       /* save r2 */ \
61         stl     r3,(3 * ULONG_SIZE)(r1) ;       /* save r3 */ \
62         stl     r4,(4 * ULONG_SIZE)(r1) ; \
63         stl     r5,(5 * ULONG_SIZE)(r1) ; \
64         stl     r6,(6 * ULONG_SIZE)(r1) ; \
65         stl     r7,(7 * ULONG_SIZE)(r1) ; \
66         stl     r8,(8 * ULONG_SIZE)(r1) ; \
67         stl     r9,(9 * ULONG_SIZE)(r1) ; \
68         stl     r10,(10 * ULONG_SIZE)(r1) ; \
69         stl     r11,(11 * ULONG_SIZE)(r1) ; \
70         stl     r12,(12 * ULONG_SIZE)(r1) ; \
71 .ifc ULONG_SIZE, 8 ; \
72         stl     r13,(17 * ULONG_SIZE)(r1) ; \
73         stl     r14,(18 * ULONG_SIZE)(r1) ; \
74         stl     r15,(19 * ULONG_SIZE)(r1) ; \
75         stl     r16,(20 * ULONG_SIZE)(r1) ; \
76         stl     r17,(21 * ULONG_SIZE)(r1) ; \
77         stl     r18,(22 * ULONG_SIZE)(r1) ; \
78         stl     r19,(23 * ULONG_SIZE)(r1) ; \
79         stl     r20,(24 * ULONG_SIZE)(r1) ; \
80         stl     r21,(25 * ULONG_SIZE)(r1) ; \
81         stl     r22,(26 * ULONG_SIZE)(r1) ; \
82         stl     r23,(27 * ULONG_SIZE)(r1) ; \
83         stl     r24,(28 * ULONG_SIZE)(r1) ; \
84         stl     r25,(29 * ULONG_SIZE)(r1) ; \
85         stl     r26,(30 * ULONG_SIZE)(r1) ; \
86         stl     r27,(31 * ULONG_SIZE)(r1) ; \
87         stl     r28,(32 * ULONG_SIZE)(r1) ; \
88         stl     r29,(33 * ULONG_SIZE)(r1) ; \
89         stl     r30,(34 * ULONG_SIZE)(r1) ; \
90         stl     r31,(35 * ULONG_SIZE)(r1) ; \
91 .endif ; \
92  \
93         mflr    r0 ; \
94         stl     r0,(13 * ULONG_SIZE)(r1) ; \
95         mfsprg2 r0 ; \
96         stl     r0,(14 * ULONG_SIZE)(r1) ; \
97         mfctr   r0 ; \
98         stl     r0,(15 * ULONG_SIZE)(r1) ; \
99         mfxer   r0 ; \
100         stl     r0,(16 * ULONG_SIZE)(r1) ; \
101  \
102         /* 76(r1) unused */ \
103         addi    r1,r1,-16 ;     /* C ABI uses 0(r1) and 4(r1)... */
104
105 #define EXCEPTION_EPILOGUE_TEMPLATE \
106         addi    r1,r1,16 ;                      /* pop ABI frame */ \
107 \
108         ll      r0,(13 * ULONG_SIZE)(r1) ; \
109         mtlr    r0 ; \
110         ll      r0,(14 * ULONG_SIZE)(r1) ; \
111         mtcr    r0 ; \
112         ll      r0,(15 * ULONG_SIZE)(r1) ; \
113         mtctr   r0 ; \
114         ll      r0,(16 * ULONG_SIZE)(r1) ; \
115         mtxer   r0 ; \
116 \
117         ll      r0,(0 * ULONG_SIZE)(r1) ; \
118         ll      r2,(2 * ULONG_SIZE)(r1) ; \
119         ll      r3,(3 * ULONG_SIZE)(r1) ; \
120         ll      r4,(4 * ULONG_SIZE)(r1) ; \
121         ll      r5,(5 * ULONG_SIZE)(r1) ; \
122         ll      r6,(6 * ULONG_SIZE)(r1) ; \
123         ll      r7,(7 * ULONG_SIZE)(r1) ; \
124         ll      r8,(8 * ULONG_SIZE)(r1) ; \
125         ll      r9,(9 * ULONG_SIZE)(r1) ; \
126         ll      r10,(10 * ULONG_SIZE)(r1) ; \
127         ll      r11,(11 * ULONG_SIZE)(r1) ; \
128         ll      r12,(12 * ULONG_SIZE)(r1) ; \
129 .ifc ULONG_SIZE, 8 ; \
130         ll      r13,(17 * ULONG_SIZE)(r1) ; \
131         ll      r14,(18 * ULONG_SIZE)(r1) ; \
132         ll      r15,(19 * ULONG_SIZE)(r1) ; \
133         ll      r16,(20 * ULONG_SIZE)(r1) ; \
134         ll      r17,(21 * ULONG_SIZE)(r1) ; \
135         ll      r18,(22 * ULONG_SIZE)(r1) ; \
136         ll      r19,(23 * ULONG_SIZE)(r1) ; \
137         ll      r20,(24 * ULONG_SIZE)(r1) ; \
138         ll      r21,(25 * ULONG_SIZE)(r1) ; \
139         ll      r22,(26 * ULONG_SIZE)(r1) ; \
140         ll      r23,(27 * ULONG_SIZE)(r1) ; \
141         ll      r24,(28 * ULONG_SIZE)(r1) ; \
142         ll      r25,(29 * ULONG_SIZE)(r1) ; \
143         ll      r26,(30 * ULONG_SIZE)(r1) ; \
144         ll      r27,(31 * ULONG_SIZE)(r1) ; \
145         ll      r28,(32 * ULONG_SIZE)(r1) ; \
146         ll      r29,(33 * ULONG_SIZE)(r1) ; \
147         ll      r30,(34 * ULONG_SIZE)(r1) ; \
148         ll      r31,(35 * ULONG_SIZE)(r1) ; \
149 .endif ; \
150         ll      r1,(1 * ULONG_SIZE)(r1) ;       /* restore stack at last */ \
151         rfi
152
153 // PPC32
154
155 #define ULONG_SIZE              4
156 #define stl                     stw
157 #define ll                      lwz
158
159 .macro EXCEPTION_PREAMBLE
160         EXCEPTION_PREAMBLE_TEMPLATE
161 .endm
162
163 .macro EXCEPTION_EPILOGUE
164         EXCEPTION_EPILOGUE_TEMPLATE
165 .endm
166
167 #undef ULONG_SIZE
168 #undef stl
169 #undef ll
170
171 // PPC64
172
173 #define ULONG_SIZE              8
174 #define stl                     std
175 #define ll                      ld
176
177 .macro EXCEPTION_PREAMBLE_64
178         EXCEPTION_PREAMBLE_TEMPLATE
179 .endm
180
181 .macro EXCEPTION_EPILOGUE_64
182         EXCEPTION_EPILOGUE_TEMPLATE
183 .endm
184
185 #undef ULONG_SIZE
186 #undef stl
187 #undef ll
188
189 #define ULONG_SIZE 4
190 #define STACKFRAME_MINSIZE 16
191
192 #else /* !CONFIG_PPC_64BITSUPPORT */
193
194 #ifdef __powerpc64__
195
196 #define ULONG_SIZE 8
197 #define STACKFRAME_MINSIZE 48
198 #define stl std
199 #define ll  ld
200
201 #else
202
203 #define ULONG_SIZE 4
204 #define STACKFRAME_MINSIZE 16
205 #define stl stw
206 #define ll  lwz
207
208 #endif
209
210 .macro EXCEPTION_PREAMBLE
211     mtsprg1 r1 /* scratch */
212     mfsprg0 r1 /* exception stack in sprg0 */
213     addi    r1, r1, -(20 * ULONG_SIZE) /* push exception frame */
214
215     stl     r0,  ( 0 * ULONG_SIZE)(r1) /* save r0 */
216     mfsprg1 r0
217     stl     r0,  ( 1 * ULONG_SIZE)(r1) /* save r1 */
218     stl     r2,  ( 2 * ULONG_SIZE)(r1) /* save r2 */
219     stl     r3,  ( 3 * ULONG_SIZE)(r1) /* save r3 */
220     stl     r4,  ( 4 * ULONG_SIZE)(r1)
221     stl     r5,  ( 5 * ULONG_SIZE)(r1)
222     stl     r6,  ( 6 * ULONG_SIZE)(r1)
223     stl     r7,  ( 7 * ULONG_SIZE)(r1)
224     stl     r8,  ( 8 * ULONG_SIZE)(r1)
225     stl     r9,  ( 9 * ULONG_SIZE)(r1)
226     stl     r10, (10 * ULONG_SIZE)(r1)
227     stl     r11, (11 * ULONG_SIZE)(r1)
228     stl     r12, (12 * ULONG_SIZE)(r1)
229
230     mflr    r0
231     stl     r0,  (13 * ULONG_SIZE)(r1)
232     mfcr    r0
233     stl     r0,  (14 * ULONG_SIZE)(r1)
234     mfctr   r0
235     stl     r0,  (15 * ULONG_SIZE)(r1)
236     mfxer   r0
237     stl     r0,  (16 * ULONG_SIZE)(r1)
238
239     addi r1, r1, -STACKFRAME_MINSIZE /* C ABI saves LR and SP */
240 .endm
241
242 .macro EXCEPTION_EPILOGUE
243     addi r1, r1,  STACKFRAME_MINSIZE /* pop ABI frame */
244
245     ll    r0,  (13 * ULONG_SIZE)(r1)
246     mtlr  r0
247     ll    r0,  (14 * ULONG_SIZE)(r1)
248     mtcr  r0
249     ll    r0,  (15 * ULONG_SIZE)(r1)
250     mtctr r0
251     ll    r0,  (16 * ULONG_SIZE)(r1)
252     mtxer r0
253
254     ll    r0,  ( 0 * ULONG_SIZE)(r1)
255     ll    r2,  ( 2 * ULONG_SIZE)(r1)
256     ll    r3,  ( 3 * ULONG_SIZE)(r1)
257     ll    r4,  ( 4 * ULONG_SIZE)(r1)
258     ll    r5,  ( 5 * ULONG_SIZE)(r1)
259     ll    r6,  ( 6 * ULONG_SIZE)(r1)
260     ll    r7,  ( 7 * ULONG_SIZE)(r1)
261     ll    r8,  ( 8 * ULONG_SIZE)(r1)
262     ll    r9,  ( 9 * ULONG_SIZE)(r1)
263     ll    r10, (10 * ULONG_SIZE)(r1)
264     ll    r11, (11 * ULONG_SIZE)(r1)
265     ll    r12, (12 * ULONG_SIZE)(r1)
266
267     ll    r1,  ( 1 * ULONG_SIZE)(r1) /* restore stack at last */
268     RFI
269 .endm
270
271 #endif /* !CONFIG_PPC_64BITSUPPORT */
272
273 /************************************************************************/
274 /*      vectors                                                         */
275 /************************************************************************/
276
277         .section .text.vectors, "ax"
278 GLOBL(__vectors):
279         nop                     // NULL-jmp trap
280 1:      nop                     //
281         b       1b
282
283 call_dsi_exception:
284         LOAD_REG_FUNC(r3, dsi_exception)
285         mtctr   r3
286         bctrl
287         b       exception_return
288
289 call_isi_exception:
290         LOAD_REG_FUNC(r3, isi_exception)
291         mtctr   r3
292         bctrl
293         b       exception_return
294
295 exception_return:
296         EXCEPTION_EPILOGUE
297
298 trap_error:
299         lis     r1, 0x8000                      /* r1=0x80000000 */
300         add.    r1,r1,r1                        /* r1=r1+r1 (high 32bit !0) */
301         beq     1f
302
303         mfmsr   r1                              /* unset MSR_SF */
304         clrldi  r1,r1,1
305         mtmsrd  r1
306 1:
307         mflr    r3
308         LOAD_REG_FUNC(r4, unexpected_excep)
309         mtctr r4
310         bctr
311
312 VECTOR( 0x100, "SRE" ):
313         b       _entry
314
315 ILLEGAL_VECTOR( 0x200 )
316
317 VECTOR( 0x300, "DSI" ):
318         b       real_dsi
319
320 ILLEGAL_VECTOR( 0x380 )
321
322 VECTOR( 0x400, "ISI" ):
323         b       real_isi
324
325 ILLEGAL_VECTOR( 0x480 )
326
327         ILLEGAL_VECTOR( 0x500 )
328         ILLEGAL_VECTOR( 0x600 )
329         ILLEGAL_VECTOR( 0x700 )
330
331 VECTOR( 0x800, "FPU" ):
332         mtsprg1 r3
333         mfsrr1  r3
334         ori     r3,r3,0x2000
335         mtsrr1  r3
336         mfsprg1 r3
337         RFI
338
339 ILLEGAL_VECTOR( 0x900 )
340 ILLEGAL_VECTOR( 0xa00 )
341 ILLEGAL_VECTOR( 0xb00 )
342 ILLEGAL_VECTOR( 0xc00 )
343 ILLEGAL_VECTOR( 0xd00 )
344 ILLEGAL_VECTOR( 0xe00 )
345 ILLEGAL_VECTOR( 0xf00 )
346 ILLEGAL_VECTOR( 0xf20 )
347 ILLEGAL_VECTOR( 0x1000 )
348 ILLEGAL_VECTOR( 0x1100 )
349 ILLEGAL_VECTOR( 0x1200 )
350 ILLEGAL_VECTOR( 0x1300 )
351 ILLEGAL_VECTOR( 0x1400 )
352 ILLEGAL_VECTOR( 0x1500 )
353 ILLEGAL_VECTOR( 0x1600 )
354 ILLEGAL_VECTOR( 0x1700 )
355
356 #ifdef CONFIG_PPC_64BITSUPPORT
357
358 VECTOR( 0x2000, "DSI_64" ):
359         EXCEPTION_PREAMBLE_64
360         LOAD_REG_IMMEDIATE(r3, dsi_exception)
361         mtctr   r3
362         bctrl
363         EXCEPTION_EPILOGUE_64
364
365 VECTOR( 0x2200, "ISI_64" ):
366         EXCEPTION_PREAMBLE_64
367         LOAD_REG_IMMEDIATE(r3, isi_exception)
368         mtctr   r3
369         bctrl
370         EXCEPTION_EPILOGUE_64
371
372 #endif
373
374 real_dsi:
375         EXCEPTION_PREAMBLE
376         b       call_dsi_exception
377
378 real_isi:
379         EXCEPTION_PREAMBLE
380         b       call_isi_exception
381
382 GLOBL(__vectors_end):
383
384 /************************************************************************/
385 /*      entry                                                           */
386 /************************************************************************/
387
388 GLOBL(_entry):
389
390 #ifdef CONFIG_PPC_64BITSUPPORT
391         li      r0,0
392
393         lis     r3, 0x8000                      /* r1=0x80000000 */
394         add.    r3,r3,r3                        /* r1=r1+r1 (high 32bit !0) */
395         beq     no_64bit                        /* only true when !MSR_SF */
396
397         /* clear MSR, disable MMU, SF */
398         mtmsrd  r0
399         b       real_entry
400
401 no_64bit:
402         /* clear MSR, disable MMU */
403         mtmsr   r0
404
405 real_entry:
406 #endif
407
408         /* copy exception vectors */
409
410         LOAD_REG_IMMEDIATE(r3, __vectors)
411         li      r4,0
412         li      r5,__vectors_end - __vectors + 16
413         rlwinm  r5,r5,0,0,28
414 1:      lwz     r6,0(r3)
415         lwz     r7,4(r3)
416         lwz     r8,8(r3)
417         lwz     r9,12(r3)
418         stw     r6,0(r4)
419         stw     r7,4(r4)
420         stw     r8,8(r4)
421         stw     r9,12(r4)
422         dcbst   0,r4
423         sync
424         icbi    0,r4
425         sync
426         addi    r5,r5,-16
427         addi    r3,r3,16
428         addi    r4,r4,16
429         cmpwi   r5,0
430         bgt     1b
431         isync
432
433         bl compute_ramsize
434
435         /* Memory map:
436          *
437          * Top +-------------------------+
438          *     |                         |
439          *     | ROM into RAM (1 MB)     |
440          *     |                         |
441          *     +-------------------------+
442          *     |                         |
443          *     | MMU Hash Table (64 kB)  |
444          *     |                         |
445          *     +-------------------------+
446          *     |                         |
447          *     | Exception Stack (32 kB) |
448          *     |                         |
449          *     +-------------------------+
450          *     |                         |
451          *     | Stack (64 kB)           |
452          *     |                         |
453          *     +-------------------------+
454          *     |                         |
455          *     | Client Stack (64 kB)    |
456          *     |                         |
457          *     +-------------------------+
458          *     |                         |
459          *     | Malloc Zone (2 MiB)     |
460          *     |                         |
461          *     +-------------------------+
462          *     :                         :
463          * Bottom
464          */
465
466         addis   r1, r3, -16             /* ramsize - 1MB */
467
468         /* setup hash table */
469
470         addis   r1, r1, -1              /* - 64 kB */
471         clrrwi  r1, r1, 5*4             /* & ~0xfffff */
472
473         /* setup exception stack */
474
475         mtsprg0 r1
476
477         /* setup stack */
478
479         addi    r1, r1, -32768          /* - 32 kB */
480
481         /* save memory size in stack */
482
483 #ifdef __powerpc64__
484         /* set up TOC pointer */
485
486         LOAD_REG_IMMEDIATE(r2, setup_mmu)
487         ld r2, 8(r2)
488 #endif
489
490         bl      BRANCH_LABEL(setup_mmu)
491         bl      BRANCH_LABEL(entry)
492 1:      nop
493         b       1b
494
495
496         /* According to IEEE 1275, PPC bindings:
497          *
498          *      MSR = FP, ME + (DR|IR)
499          *      r1 = stack (32 K + 32 bytes link area above)
500          *      r5 = client interface handler
501          *      r6 = address of client program arguments (unused)
502          *      r7 = length of client program arguments (unused)
503          *
504          *      Yaboot and Linux use r3 and r4 for initrd address and size
505          */
506         .data
507 saved_stack:
508     DATA_LONG(0)
509         .previous
510         /* void call_elf( arg1, arg2, entry ) */
511 _GLOBAL(call_elf):
512         mflr    r0
513         PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
514         PPC_STL  r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
515         mtlr    r5
516         LOAD_REG_IMMEDIATE(r8, saved_stack)             // save our stack pointer
517         PPC_STL r1,0(r8)
518         mfsdr1  r1
519         addi    r1, r1, -32768          /* - 32 KiB exception stack */
520         addis   r1, r1, -1                      /* - 64 KiB stack */
521         LOAD_REG_IMMEDIATE(r5, of_client_callback)      // r5 = callback
522         li      r6,0                    // r6 = address of client program arguments (unused)
523         li      r7,0                    // r7 = length of client program arguments (unused)
524         li      r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
525         MTMSRD(r0)
526         blrl
527
528 #ifdef CONFIG_PPC64
529     /* Restore SF bit */
530     LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
531     MTMSRD(r0)
532 #endif
533         LOAD_REG_IMMEDIATE(r8, saved_stack)             // restore stack pointer
534         mr      r1,r8
535         PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
536         mtlr    r0
537         addi    r1, r1, STACKFRAME_MINSIZE
538         // XXX: should restore r12-r31 etc..
539         // we should not really come here though
540         blr
541
542 #ifdef __powerpc64__
543 #define STKOFF STACKFRAME_MINSIZE
544 #define SAVE_SPACE 320
545 #else
546 #define STKOFF 8
547 #define SAVE_SPACE 144
548 #endif
549 GLOBL(of_client_callback):
550
551 #ifdef CONFIG_PPC64
552     PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1)
553 #else
554     PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */
555 #endif
556
557         /* save r4 */
558
559     PPC_STL r4, STKOFF(r1)
560
561         /* save lr */
562
563         mflr    r4
564     PPC_STL r4, PPC_LR_STKOFF(r1)
565
566         /* restore OF stack */
567
568         LOAD_REG_IMMEDIATE(r4, saved_stack)
569     PPC_LL  r4, 0(r4)
570
571         PPC_STLU r4,-SAVE_SPACE(r4)
572         PPC_STL r1,(STKOFF)(r4)         // save caller stack
573         mr      r1,r4
574
575     PPC_STL r2,  (STKOFF +  1 * ULONG_SIZE)(r1)
576     PPC_STL r0,  (STKOFF +  2 * ULONG_SIZE)(r1)
577
578         /* save ctr, cr and xer */
579
580         mfctr   r2
581     PPC_STL r2,  (STKOFF +  3 * ULONG_SIZE)(r1)
582         mfcr    r2
583     PPC_STL r2,  (STKOFF +  4 * ULONG_SIZE)(r1)
584         mfxer   r2
585     PPC_STL r2,  (STKOFF +  5 * ULONG_SIZE)(r1)
586
587         /* save r5 - r31 */
588
589     PPC_STL r5,  (STKOFF +  6 * ULONG_SIZE)(r1)
590     PPC_STL r6,  (STKOFF +  7 * ULONG_SIZE)(r1)
591     PPC_STL r7,  (STKOFF +  8 * ULONG_SIZE)(r1)
592     PPC_STL r8,  (STKOFF +  9 * ULONG_SIZE)(r1)
593     PPC_STL r9,  (STKOFF + 10 * ULONG_SIZE)(r1)
594     PPC_STL r10, (STKOFF + 11 * ULONG_SIZE)(r1)
595     PPC_STL r11, (STKOFF + 12 * ULONG_SIZE)(r1)
596     PPC_STL r12, (STKOFF + 13 * ULONG_SIZE)(r1)
597     PPC_STL r13, (STKOFF + 14 * ULONG_SIZE)(r1)
598     PPC_STL r14, (STKOFF + 15 * ULONG_SIZE)(r1)
599     PPC_STL r15, (STKOFF + 16 * ULONG_SIZE)(r1)
600     PPC_STL r16, (STKOFF + 17 * ULONG_SIZE)(r1)
601     PPC_STL r17, (STKOFF + 18 * ULONG_SIZE)(r1)
602     PPC_STL r18, (STKOFF + 19 * ULONG_SIZE)(r1)
603     PPC_STL r19, (STKOFF + 20 * ULONG_SIZE)(r1)
604     PPC_STL r20, (STKOFF + 21 * ULONG_SIZE)(r1)
605     PPC_STL r21, (STKOFF + 22 * ULONG_SIZE)(r1)
606     PPC_STL r22, (STKOFF + 23 * ULONG_SIZE)(r1)
607     PPC_STL r23, (STKOFF + 24 * ULONG_SIZE)(r1)
608     PPC_STL r24, (STKOFF + 25 * ULONG_SIZE)(r1)
609     PPC_STL r25, (STKOFF + 26 * ULONG_SIZE)(r1)
610     PPC_STL r26, (STKOFF + 27 * ULONG_SIZE)(r1)
611     PPC_STL r27, (STKOFF + 28 * ULONG_SIZE)(r1)
612     PPC_STL r28, (STKOFF + 29 * ULONG_SIZE)(r1)
613     PPC_STL r29, (STKOFF + 30 * ULONG_SIZE)(r1)
614     PPC_STL r30, (STKOFF + 31 * ULONG_SIZE)(r1)
615     PPC_STL r31, (STKOFF + 32 * ULONG_SIZE)(r1)
616
617 #ifdef CONFIG_PPC64
618     LOAD_REG_IMMEDIATE(r2, of_client_interface)
619     ld  r2, 8(r2)
620 #endif
621     bl  BRANCH_LABEL(of_client_interface)
622
623         /* restore r5 - r31 */
624
625     PPC_LL  r5,  (STKOFF +  6 * ULONG_SIZE)(r1)
626     PPC_LL  r6,  (STKOFF +  7 * ULONG_SIZE)(r1)
627     PPC_LL  r7,  (STKOFF +  8 * ULONG_SIZE)(r1)
628     PPC_LL  r8,  (STKOFF +  9 * ULONG_SIZE)(r1)
629     PPC_LL  r9,  (STKOFF + 10 * ULONG_SIZE)(r1)
630     PPC_LL  r10, (STKOFF + 11 * ULONG_SIZE)(r1)
631     PPC_LL  r11, (STKOFF + 12 * ULONG_SIZE)(r1)
632     PPC_LL  r12, (STKOFF + 13 * ULONG_SIZE)(r1)
633     PPC_LL  r13, (STKOFF + 14 * ULONG_SIZE)(r1)
634     PPC_LL  r14, (STKOFF + 15 * ULONG_SIZE)(r1)
635     PPC_LL  r15, (STKOFF + 16 * ULONG_SIZE)(r1)
636     PPC_LL  r16, (STKOFF + 17 * ULONG_SIZE)(r1)
637     PPC_LL  r17, (STKOFF + 18 * ULONG_SIZE)(r1)
638     PPC_LL  r18, (STKOFF + 19 * ULONG_SIZE)(r1)
639     PPC_LL  r19, (STKOFF + 20 * ULONG_SIZE)(r1)
640     PPC_LL  r20, (STKOFF + 21 * ULONG_SIZE)(r1)
641     PPC_LL  r21, (STKOFF + 22 * ULONG_SIZE)(r1)
642     PPC_LL  r22, (STKOFF + 23 * ULONG_SIZE)(r1)
643     PPC_LL  r23, (STKOFF + 24 * ULONG_SIZE)(r1)
644     PPC_LL  r24, (STKOFF + 25 * ULONG_SIZE)(r1)
645     PPC_LL  r25, (STKOFF + 26 * ULONG_SIZE)(r1)
646     PPC_LL  r26, (STKOFF + 27 * ULONG_SIZE)(r1)
647     PPC_LL  r27, (STKOFF + 28 * ULONG_SIZE)(r1)
648     PPC_LL  r28, (STKOFF + 29 * ULONG_SIZE)(r1)
649     PPC_LL  r29, (STKOFF + 30 * ULONG_SIZE)(r1)
650     PPC_LL  r30, (STKOFF + 31 * ULONG_SIZE)(r1)
651     PPC_LL  r31, (STKOFF + 32 * ULONG_SIZE)(r1)
652
653         /* restore ctr, cr and xer */
654
655     PPC_LL  r2,  (STKOFF +  3 * ULONG_SIZE)(r1)
656         mtctr   r2
657     PPC_LL  r2,  (STKOFF +  4 * ULONG_SIZE)(r1)
658         mtcr    r2
659     PPC_LL  r2,  (STKOFF +  5 * ULONG_SIZE)(r1)
660         mtxer   r2
661
662         /* restore r0 and r2 */
663
664     PPC_LL  r2,  (STKOFF +  1 * ULONG_SIZE)(r1)
665     PPC_LL  r0,  (STKOFF +  2 * ULONG_SIZE)(r1)
666
667         /* restore caller stack */
668
669     PPC_LL  r1,  (STKOFF)(r1)
670
671     PPC_LL  r4, PPC_LR_STKOFF(r1)
672         mtlr    r4
673     PPC_LL  r4, STKOFF(r1)
674     PPC_LL  r1, 0(r1)
675
676         blr
677
678         /* rtas glue (must be reloctable) */
679 GLOBL(of_rtas_start):
680         /* r3 = argument buffer, r4 = of_rtas_start */
681         /* according to the CHRP standard, cr must be preserved (cr0/cr1 too?) */
682         blr
683 GLOBL(of_rtas_end):
684
685
686 #define CACHE_LINE_SIZE         32
687 #define LG_CACHE_LINE_SIZE      5
688
689 /* flush_icache_range( unsigned long start, unsigned long stop) */
690 _GLOBAL(flush_icache_range):
691         li      r5,CACHE_LINE_SIZE-1
692         andc    r3,r3,r5
693         subf    r4,r3,r4
694         add     r4,r4,r5
695         srwi.   r4,r4,LG_CACHE_LINE_SIZE
696         beqlr
697         mtctr   r4
698         mr      r6,r3
699 1:      dcbst   0,r3
700         addi    r3,r3,CACHE_LINE_SIZE
701         bdnz    1b
702         sync                            /* wait for dcbst's to get to ram */
703         mtctr   r4
704 2:      icbi    0,r6
705         addi    r6,r6,CACHE_LINE_SIZE
706         bdnz    2b
707         sync                            /* additional sync needed on g4 */
708         isync
709         blr
710
711         /* Get RAM size from QEMU configuration device */
712
713 #define CFG_ADDR 0xf0000510
714 #define FW_CFG_RAM_SIZE         0x03
715
716 compute_ramsize:
717         LOAD_REG_IMMEDIATE(r9, CFG_ADDR)
718         li      r0,FW_CFG_RAM_SIZE
719         sth     r0,0(r9)
720         LOAD_REG_IMMEDIATE(r9, CFG_ADDR + 2)
721         lbz     r1,0(r9)
722         lbz     r0,0(r9)
723         slwi    r0,r0,8
724         or      r1,r1,r0
725         lbz     r0,0(r9)
726         slwi    r0,r0,16
727         or      r1,r1,r0
728         lbz     r0,0(r9)
729         slwi    r0,r0,24
730         or      r3,r1,r0
731         blr
732
733         /* Hard reset vector */
734         .section .romentry,"ax"
735         bl      _entry