Add qemu 2.4.0
[kvmfornfv.git] / qemu / 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 VECTOR( 0x100, "SRE" ):
284         b       _entry
285
286 trap_error:
287         lis     r1, 0x8000                      /* r1=0x80000000 */
288         add.    r1,r1,r1                        /* r1=r1+r1 (high 32bit !0) */
289         beq     1f
290
291         mfmsr   r1                              /* unset MSR_SF */
292         clrldi  r1,r1,1
293         mtmsrd  r1
294 1:
295         mflr    r3
296         LOAD_REG_FUNC(r4, unexpected_excep)
297         mtctr r4
298         bctr
299
300 ILLEGAL_VECTOR( 0x200 )
301
302 VECTOR( 0x300, "DSI" ):
303         b       real_dsi
304
305 ILLEGAL_VECTOR( 0x380 )
306
307 VECTOR( 0x400, "ISI" ):
308         b       real_isi
309
310 ILLEGAL_VECTOR( 0x480 )
311
312         ILLEGAL_VECTOR( 0x500 )
313         ILLEGAL_VECTOR( 0x600 )
314         ILLEGAL_VECTOR( 0x700 )
315
316 VECTOR( 0x800, "FPU" ):
317         mtsprg1 r3
318         mfsrr1  r3
319         ori     r3,r3,0x2000
320         mtsrr1  r3
321         mfsprg1 r3
322         RFI
323
324 ILLEGAL_VECTOR( 0x900 )
325 ILLEGAL_VECTOR( 0xa00 )
326 ILLEGAL_VECTOR( 0xb00 )
327 ILLEGAL_VECTOR( 0xc00 )
328 ILLEGAL_VECTOR( 0xd00 )
329 ILLEGAL_VECTOR( 0xe00 )
330 ILLEGAL_VECTOR( 0xf00 )
331 ILLEGAL_VECTOR( 0xf20 )
332 ILLEGAL_VECTOR( 0x1000 )
333 ILLEGAL_VECTOR( 0x1100 )
334 ILLEGAL_VECTOR( 0x1200 )
335 ILLEGAL_VECTOR( 0x1300 )
336 ILLEGAL_VECTOR( 0x1400 )
337 ILLEGAL_VECTOR( 0x1500 )
338 ILLEGAL_VECTOR( 0x1600 )
339 ILLEGAL_VECTOR( 0x1700 )
340
341 #ifdef CONFIG_PPC_64BITSUPPORT
342
343 VECTOR( 0x2000, "DSI_64" ):
344         EXCEPTION_PREAMBLE_64
345         LOAD_REG_IMMEDIATE(r3, dsi_exception)
346         mtctr   r3
347         bctrl
348         EXCEPTION_EPILOGUE_64
349
350 VECTOR( 0x2200, "ISI_64" ):
351         EXCEPTION_PREAMBLE_64
352         LOAD_REG_IMMEDIATE(r3, isi_exception)
353         mtctr   r3
354         bctrl
355         EXCEPTION_EPILOGUE_64
356
357 #endif
358
359 real_dsi:
360         EXCEPTION_PREAMBLE
361         LOAD_REG_FUNC(r3, dsi_exception)
362         mtctr   r3
363         bctrl
364         b exception_return
365
366 real_isi:
367         EXCEPTION_PREAMBLE
368         LOAD_REG_FUNC(r3, isi_exception)
369         mtctr   r3
370         bctrl
371         b exception_return
372
373 exception_return:
374         EXCEPTION_EPILOGUE
375
376 GLOBL(__vectors_end):
377
378 /************************************************************************/
379 /*      entry                                                           */
380 /************************************************************************/
381
382 GLOBL(_entry):
383
384 #ifdef CONFIG_PPC_64BITSUPPORT
385         li      r0,0
386
387         lis     r3, 0x8000                      /* r1=0x80000000 */
388         add.    r3,r3,r3                        /* r1=r1+r1 (high 32bit !0) */
389         beq     no_64bit                        /* only true when !MSR_SF */
390
391         /* clear MSR, disable MMU, SF */
392         mtmsrd  r0
393         b       real_entry
394
395 no_64bit:
396         /* clear MSR, disable MMU */
397         mtmsr   r0
398
399 real_entry:
400 #endif
401
402         /* copy exception vectors */
403
404         LOAD_REG_IMMEDIATE(r3, __vectors)
405         li      r4,0
406         li      r5,__vectors_end - __vectors + 16
407         rlwinm  r5,r5,0,0,28
408 1:      lwz     r6,0(r3)
409         lwz     r7,4(r3)
410         lwz     r8,8(r3)
411         lwz     r9,12(r3)
412         stw     r6,0(r4)
413         stw     r7,4(r4)
414         stw     r8,8(r4)
415         stw     r9,12(r4)
416         dcbst   0,r4
417         sync
418         icbi    0,r4
419         sync
420         addi    r5,r5,-16
421         addi    r3,r3,16
422         addi    r4,r4,16
423         cmpwi   r5,0
424         bgt     1b
425         isync
426
427         bl compute_ramsize
428
429         /* Memory map:
430          *
431          * Top +-------------------------+
432          *     |                         |
433          *     | ROM into RAM (1 MB)     |
434          *     |                         |
435          *     +-------------------------+
436          *     |                         |
437          *     | MMU Hash Table (64 kB)  |
438          *     |                         |
439          *     +-------------------------+
440          *     |                         |
441          *     | Exception Stack (32 kB) |
442          *     |                         |
443          *     +-------------------------+
444          *     |                         |
445          *     | Stack (64 kB)           |
446          *     |                         |
447          *     +-------------------------+
448          *     |                         |
449          *     | Client Stack (64 kB)    |
450          *     |                         |
451          *     +-------------------------+
452          *     |                         |
453          *     | Malloc Zone (2 MiB)     |
454          *     |                         |
455          *     +-------------------------+
456          *     :                         :
457          * Bottom
458          */
459
460         addis   r1, r3, -16             /* ramsize - 1MB */
461
462         /* setup hash table */
463
464         addis   r1, r1, -1              /* - 64 kB */
465         clrrwi  r1, r1, 5*4             /* & ~0xfffff */
466
467         /* setup exception stack */
468
469         mtsprg0 r1
470
471         /* setup stack */
472
473         addi    r1, r1, -32768          /* - 32 kB */
474
475         /* save memory size in stack */
476
477 #ifdef __powerpc64__
478         /* set up TOC pointer */
479
480         LOAD_REG_IMMEDIATE(r2, setup_mmu)
481         ld r2, 8(r2)
482 #endif
483
484         bl      BRANCH_LABEL(setup_mmu)
485         bl      BRANCH_LABEL(entry)
486 1:      nop
487         b       1b
488
489
490         /* According to IEEE 1275, PPC bindings:
491          *
492          *      MSR = FP, ME + (DR|IR)
493          *      r1 = stack (32 K + 32 bytes link area above)
494          *      r5 = client interface handler
495          *      r6 = address of client program arguments (unused)
496          *      r7 = length of client program arguments (unused)
497          *
498          *      Yaboot and Linux use r3 and r4 for initrd address and size
499          */
500         .data
501 saved_stack:
502     DATA_LONG(0)
503         .previous
504         /* void call_elf( arg1, arg2, entry ) */
505 _GLOBAL(call_elf):
506         mflr    r0
507         PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
508         PPC_STL  r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
509         mtlr    r5
510         LOAD_REG_IMMEDIATE(r8, saved_stack)             // save our stack pointer
511         PPC_STL r1,0(r8)
512         mfsdr1  r1
513         addi    r1, r1, -32768          /* - 32 KiB exception stack */
514         addis   r1, r1, -1                      /* - 64 KiB stack */
515         LOAD_REG_IMMEDIATE(r5, of_client_callback)      // r5 = callback
516         li      r6,0                    // r6 = address of client program arguments (unused)
517         li      r7,0                    // r7 = length of client program arguments (unused)
518         li      r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
519         MTMSRD(r0)
520         blrl
521
522 #ifdef CONFIG_PPC64
523     /* Restore SF bit */
524     LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
525     MTMSRD(r0)
526 #endif
527         LOAD_REG_IMMEDIATE(r8, saved_stack)             // restore stack pointer
528         mr      r1,r8
529         PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
530         mtlr    r0
531         addi    r1, r1, STACKFRAME_MINSIZE
532         // XXX: should restore r12-r31 etc..
533         // we should not really come here though
534         blr
535
536 #ifdef __powerpc64__
537 #define STKOFF STACKFRAME_MINSIZE
538 #define SAVE_SPACE 320
539 #else
540 #define STKOFF 8
541 #define SAVE_SPACE 144
542 #endif
543 GLOBL(of_client_callback):
544
545 #ifdef CONFIG_PPC64
546     PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1)
547 #else
548     PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */
549 #endif
550
551         /* save r4 */
552
553     PPC_STL r4, STKOFF(r1)
554
555         /* save lr */
556
557         mflr    r4
558     PPC_STL r4, PPC_LR_STKOFF(r1)
559
560         /* restore OF stack */
561
562         LOAD_REG_IMMEDIATE(r4, saved_stack)
563     PPC_LL  r4, 0(r4)
564
565         PPC_STLU r4,-SAVE_SPACE(r4)
566         PPC_STL r1,(STKOFF)(r4)         // save caller stack
567         mr      r1,r4
568
569     PPC_STL r2,  (STKOFF +  1 * ULONG_SIZE)(r1)
570     PPC_STL r0,  (STKOFF +  2 * ULONG_SIZE)(r1)
571
572         /* save ctr, cr and xer */
573
574         mfctr   r2
575     PPC_STL r2,  (STKOFF +  3 * ULONG_SIZE)(r1)
576         mfcr    r2
577     PPC_STL r2,  (STKOFF +  4 * ULONG_SIZE)(r1)
578         mfxer   r2
579     PPC_STL r2,  (STKOFF +  5 * ULONG_SIZE)(r1)
580
581         /* save r5 - r31 */
582
583     PPC_STL r5,  (STKOFF +  6 * ULONG_SIZE)(r1)
584     PPC_STL r6,  (STKOFF +  7 * ULONG_SIZE)(r1)
585     PPC_STL r7,  (STKOFF +  8 * ULONG_SIZE)(r1)
586     PPC_STL r8,  (STKOFF +  9 * ULONG_SIZE)(r1)
587     PPC_STL r9,  (STKOFF + 10 * ULONG_SIZE)(r1)
588     PPC_STL r10, (STKOFF + 11 * ULONG_SIZE)(r1)
589     PPC_STL r11, (STKOFF + 12 * ULONG_SIZE)(r1)
590     PPC_STL r12, (STKOFF + 13 * ULONG_SIZE)(r1)
591     PPC_STL r13, (STKOFF + 14 * ULONG_SIZE)(r1)
592     PPC_STL r14, (STKOFF + 15 * ULONG_SIZE)(r1)
593     PPC_STL r15, (STKOFF + 16 * ULONG_SIZE)(r1)
594     PPC_STL r16, (STKOFF + 17 * ULONG_SIZE)(r1)
595     PPC_STL r17, (STKOFF + 18 * ULONG_SIZE)(r1)
596     PPC_STL r18, (STKOFF + 19 * ULONG_SIZE)(r1)
597     PPC_STL r19, (STKOFF + 20 * ULONG_SIZE)(r1)
598     PPC_STL r20, (STKOFF + 21 * ULONG_SIZE)(r1)
599     PPC_STL r21, (STKOFF + 22 * ULONG_SIZE)(r1)
600     PPC_STL r22, (STKOFF + 23 * ULONG_SIZE)(r1)
601     PPC_STL r23, (STKOFF + 24 * ULONG_SIZE)(r1)
602     PPC_STL r24, (STKOFF + 25 * ULONG_SIZE)(r1)
603     PPC_STL r25, (STKOFF + 26 * ULONG_SIZE)(r1)
604     PPC_STL r26, (STKOFF + 27 * ULONG_SIZE)(r1)
605     PPC_STL r27, (STKOFF + 28 * ULONG_SIZE)(r1)
606     PPC_STL r28, (STKOFF + 29 * ULONG_SIZE)(r1)
607     PPC_STL r29, (STKOFF + 30 * ULONG_SIZE)(r1)
608     PPC_STL r30, (STKOFF + 31 * ULONG_SIZE)(r1)
609     PPC_STL r31, (STKOFF + 32 * ULONG_SIZE)(r1)
610
611 #ifdef CONFIG_PPC64
612     LOAD_REG_IMMEDIATE(r2, of_client_interface)
613     ld  r2, 8(r2)
614 #endif
615     bl  BRANCH_LABEL(of_client_interface)
616
617         /* restore r5 - r31 */
618
619     PPC_LL  r5,  (STKOFF +  6 * ULONG_SIZE)(r1)
620     PPC_LL  r6,  (STKOFF +  7 * ULONG_SIZE)(r1)
621     PPC_LL  r7,  (STKOFF +  8 * ULONG_SIZE)(r1)
622     PPC_LL  r8,  (STKOFF +  9 * ULONG_SIZE)(r1)
623     PPC_LL  r9,  (STKOFF + 10 * ULONG_SIZE)(r1)
624     PPC_LL  r10, (STKOFF + 11 * ULONG_SIZE)(r1)
625     PPC_LL  r11, (STKOFF + 12 * ULONG_SIZE)(r1)
626     PPC_LL  r12, (STKOFF + 13 * ULONG_SIZE)(r1)
627     PPC_LL  r13, (STKOFF + 14 * ULONG_SIZE)(r1)
628     PPC_LL  r14, (STKOFF + 15 * ULONG_SIZE)(r1)
629     PPC_LL  r15, (STKOFF + 16 * ULONG_SIZE)(r1)
630     PPC_LL  r16, (STKOFF + 17 * ULONG_SIZE)(r1)
631     PPC_LL  r17, (STKOFF + 18 * ULONG_SIZE)(r1)
632     PPC_LL  r18, (STKOFF + 19 * ULONG_SIZE)(r1)
633     PPC_LL  r19, (STKOFF + 20 * ULONG_SIZE)(r1)
634     PPC_LL  r20, (STKOFF + 21 * ULONG_SIZE)(r1)
635     PPC_LL  r21, (STKOFF + 22 * ULONG_SIZE)(r1)
636     PPC_LL  r22, (STKOFF + 23 * ULONG_SIZE)(r1)
637     PPC_LL  r23, (STKOFF + 24 * ULONG_SIZE)(r1)
638     PPC_LL  r24, (STKOFF + 25 * ULONG_SIZE)(r1)
639     PPC_LL  r25, (STKOFF + 26 * ULONG_SIZE)(r1)
640     PPC_LL  r26, (STKOFF + 27 * ULONG_SIZE)(r1)
641     PPC_LL  r27, (STKOFF + 28 * ULONG_SIZE)(r1)
642     PPC_LL  r28, (STKOFF + 29 * ULONG_SIZE)(r1)
643     PPC_LL  r29, (STKOFF + 30 * ULONG_SIZE)(r1)
644     PPC_LL  r30, (STKOFF + 31 * ULONG_SIZE)(r1)
645     PPC_LL  r31, (STKOFF + 32 * ULONG_SIZE)(r1)
646
647         /* restore ctr, cr and xer */
648
649     PPC_LL  r2,  (STKOFF +  3 * ULONG_SIZE)(r1)
650         mtctr   r2
651     PPC_LL  r2,  (STKOFF +  4 * ULONG_SIZE)(r1)
652         mtcr    r2
653     PPC_LL  r2,  (STKOFF +  5 * ULONG_SIZE)(r1)
654         mtxer   r2
655
656         /* restore r0 and r2 */
657
658     PPC_LL  r2,  (STKOFF +  1 * ULONG_SIZE)(r1)
659     PPC_LL  r0,  (STKOFF +  2 * ULONG_SIZE)(r1)
660
661         /* restore caller stack */
662
663     PPC_LL  r1,  (STKOFF)(r1)
664
665     PPC_LL  r4, PPC_LR_STKOFF(r1)
666         mtlr    r4
667     PPC_LL  r4, STKOFF(r1)
668     PPC_LL  r1, 0(r1)
669
670         blr
671
672         /* rtas glue (must be reloctable) */
673 GLOBL(of_rtas_start):
674         /* r3 = argument buffer, r4 = of_rtas_start */
675         /* according to the CHRP standard, cr must be preserved (cr0/cr1 too?) */
676         blr
677 GLOBL(of_rtas_end):
678
679
680 #define CACHE_LINE_SIZE         32
681 #define LG_CACHE_LINE_SIZE      5
682
683 /* flush_icache_range( unsigned long start, unsigned long stop) */
684 _GLOBAL(flush_icache_range):
685         li      r5,CACHE_LINE_SIZE-1
686         andc    r3,r3,r5
687         subf    r4,r3,r4
688         add     r4,r4,r5
689         srwi.   r4,r4,LG_CACHE_LINE_SIZE
690         beqlr
691         mtctr   r4
692         mr      r6,r3
693 1:      dcbst   0,r3
694         addi    r3,r3,CACHE_LINE_SIZE
695         bdnz    1b
696         sync                            /* wait for dcbst's to get to ram */
697         mtctr   r4
698 2:      icbi    0,r6
699         addi    r6,r6,CACHE_LINE_SIZE
700         bdnz    2b
701         sync                            /* additional sync needed on g4 */
702         isync
703         blr
704
705         /* Get RAM size from QEMU configuration device */
706
707 #define CFG_ADDR 0xf0000510
708 #define FW_CFG_RAM_SIZE         0x03
709
710 compute_ramsize:
711         LOAD_REG_IMMEDIATE(r9, CFG_ADDR)
712         li      r0,FW_CFG_RAM_SIZE
713         sth     r0,0(r9)
714         LOAD_REG_IMMEDIATE(r9, CFG_ADDR + 2)
715         lbz     r1,0(r9)
716         lbz     r0,0(r9)
717         slwi    r0,r0,8
718         or      r1,r1,r0
719         lbz     r0,0(r9)
720         slwi    r0,r0,16
721         or      r1,r1,r0
722         lbz     r0,0(r9)
723         slwi    r0,r0,24
724         or      r3,r1,r0
725         blr
726
727         /* Hard reset vector */
728         .section .romentry,"ax"
729         bl      _entry