Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / arch / ppc / 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 run inside MOL
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 "asm/asmdefs.h"
18 #include "asm/processor.h"
19 #include "osi.h"
20
21 /************************************************************************/
22 /*      Macros                                                          */
23 /************************************************************************/
24
25 #define ILLEGAL_VECTOR( v )     .org __vectors + v ; bl trap_error ;
26 #define VECTOR( v, dummystr )   .org __vectors + v ; vector__##v
27
28 #define EXCEPTION_PREAMBLE \
29         mtsprg1 r1 ;            /* scratch */ \
30         mfsprg0 r1 ;            /* exception stack in sprg0 */ \
31         addi    r1,r1,-80 ;     /* push exception frame */ \
32  \
33         stw     r0,0(r1) ;      /* save r0 */ \
34         mfsprg1 r0 ; \
35         stw     r0,4(r1) ;      /* save r1 */ \
36         stw     r2,8(r1) ;      /* save r2 */ \
37         stw     r3,12(r1) ;     /* save r3 */ \
38         stw     r4,16(r1) ; \
39         stw     r5,20(r1) ; \
40         stw     r6,24(r1) ; \
41         stw     r7,28(r1) ; \
42         stw     r8,32(r1) ; \
43         stw     r9,36(r1) ; \
44         stw     r10,40(r1) ; \
45         stw     r11,44(r1) ; \
46         stw     r12,48(r1) ; \
47  \
48         mflr    r0 ; \
49         stw     r0,52(r1) ; \
50         mfcr    r0 ; \
51         stw     r0,56(r1) ; \
52         mfctr   r0 ; \
53         stw     r0,60(r1) ; \
54         mfxer   r0 ; \
55         stw     r0,64(r1) ; \
56  \
57         /* 76(r1) unused */ \
58         addi    r1,r1,-16 ;     /* call conventions uses 0(r1) and 4(r1)... */
59
60
61 /************************************************************************/
62 /*      stack space                                                     */
63 /************************************************************************/
64
65         .section .bss
66         .balign 32
67         .space  32*1024         // 32 K client stack
68 client_stack:
69         .space  128
70
71         .space  64*1024         // 64 K stack
72 stack:  .space  64
73
74         .space  32*1024         // 32 K exception stack
75 estack: .space  128
76
77
78 /************************************************************************/
79 /*      entry                                                           */
80 /************************************************************************/
81
82         .text
83 GLOBL(_start):
84         li      r0,0
85         mtmsr   r0
86
87         lis     r1,HA(estack)
88         addi    r1,r1,LO(estack)
89         mtsprg0 r1                      // setup exception stack
90         lis     r1,HA(stack)
91         addi    r1,r1,LO(stack)
92
93         // copy exception vectors
94         lis     r3,HA(__vectors)
95         addi    r3,r3,LO(__vectors)
96         li      r4,0
97         li      r5,__vectors_end - __vectors + 16
98         rlwinm  r5,r5,0,0,28
99 1:      lwz     r6,0(r3)
100         lwz     r7,4(r3)
101         lwz     r8,8(r3)
102         lwz     r9,12(r3)
103         stw     r6,0(r4)
104         stw     r7,4(r4)
105         stw     r8,8(r4)
106         stw     r9,12(r4)
107         dcbst   0,r4
108         sync
109         icbi    0,r4
110         sync
111         addi    r5,r5,-16
112         addi    r3,r3,16
113         addi    r4,r4,16
114         cmpwi   r5,0
115         bgt     1b
116         isync
117
118         bl      setup_mmu
119         bl      entry
120 1:      nop
121         b       1b
122
123
124         /* According to IEEE 1275, PPC bindings:
125          *
126          *      MSR = FP, ME + (DR|IR)
127          *      r1 = stack (32 K + 32 bytes link area above)
128          *      r5 = clint interface handler
129          *      r6 = address of client program arguments (unused)
130          *      r7 = length of client program arguments (unsed)
131          */
132 saved_stack:
133         .long   0
134         /* void call_elf( entry ) */
135 GLOBL(call_elf):
136         mflr    r0
137         stwu    r1,-16(r1)
138         stw     r0,20(r1)
139         mtlr    r3
140         lis     r8,HA(saved_stack)
141         addi    r8,r8,LO(saved_stack)           // save our stack pointer
142         stw     r1,0(r8)
143         lis     r1,HA(client_stack)
144         addi    r1,r1,LO(client_stack)
145         lis     r5,HA(of_client_callback)
146         addi    r5,r5,LO(of_client_callback)    // r5 = callback
147         li      r6,0                    // r6 = address of client program arguments (unused)
148         li      r7,0                    // r7 = length of client program arguments (unused)
149         li      r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
150         mtmsr   r0
151         blrl
152
153         lis     r8,HA(saved_stack)
154         addi    r8,r8,LO(saved_stack)           // restore stack pointer
155         mr      r1,r8
156         lwz     r0,20(r1)
157         mtlr    r0
158         addi    r1,r1,16
159         // XXX: should restore r12-r31 etc..
160         // we should not really come here though
161         blr
162
163 GLOBL(of_client_callback):
164         lis     r4,HA(saved_stack)
165         addi    r4,r4,LO(saved_stack)
166         lwz     r4,0(r4)
167         stwu    r4,-32(r4)
168         mflr    r5
169         stw     r5,32+4(r4)
170         stw     r1,8(r4)                // save caller stack
171         mr      r1,r4
172         stw     r2,12(r1)
173         stw     r0,16(r1)
174         mfctr   r2
175         stw     r2,20(r1)
176         mfcr    r2
177         stw     r2,24(r1)
178         mfxer   r2
179         stw     r2,28(r1)
180         // do we need to save more registers?
181         bl      of_client_interface
182         lwz     r4,32+4(r1)
183         mtlr    r4
184         lwz     r2,20(r1)
185         mtctr   r2
186         lwz     r2,24(r1)
187         mtcr    r2
188         lwz     r2,28(r1)
189         mtxer   r2
190         lwz     r2,12(r1)
191         lwz     r0,16(r1)
192         lwz     r1,8(r1)                // restore caller stack
193         blr
194
195         /* rtas glue (must be reloctable) */
196 GLOBL(of_rtas_start):
197         /* r3 = argument buffer, r4 = of_rtas_start */
198         /* according to the CHRP standard, cr must be preserved (cr0/cr1 too?) */
199         mr      r6,r3
200         lis     r3,HA(OSI_SC_MAGIC_R3)
201         addi    r3,r3,LO(OSI_SC_MAGIC_R3)
202         lis     r4,HA(OSI_SC_MAGIC_R4)
203         addi    r4,r4,LO(OSI_SC_MAGIC_R4)
204         li      r5,OSI_OF_RTAS
205         sc
206         blr
207 GLOBL(of_rtas_end):
208
209
210         /* used in a hack to the newworld calibration */
211 GLOBL(nw_dec_calibration):
212         .long   0
213 GLOBL(timer_calib_start):
214         lis     r3,HA(nw_dec_calibration)
215         addi    r3,r3,LO(nw_dec_calibration)
216         lwz     r3,0(r3)
217         blr
218 GLOBL(timer_calib_end):
219
220
221 /************************************************************************/
222 /*      vectors                                                         */
223 /************************************************************************/
224
225 GLOBL(__vectors):
226         nop                     // NULL-jmp trap
227 1:      nop                     //
228         b       1b
229
230 exception_return:
231         addi    r1,r1,16        // pop ABI frame
232
233         lwz     r0,52(r1)
234         mtlr    r0
235         lwz     r0,56(r1)
236         mtcr    r0
237         lwz     r0,60(r1)
238         mtctr   r0
239         lwz     r0,64(r1)
240         mtxer   r0
241
242         lwz     r0,0(r1)        // restore r0
243         lwz     r2,8(r1)        // restore r2
244         lwz     r3,12(r1)       // restore r3
245         lwz     r4,16(r1)
246         lwz     r5,20(r1)
247         lwz     r6,24(r1)
248         lwz     r7,28(r1)
249         lwz     r8,32(r1)
250         lwz     r9,36(r1)
251         lwz     r10,40(r1)
252         lwz     r11,44(r1)
253         lwz     r12,48(r1)
254         lwz     r1,4(r1)        // restore r1
255         rfi
256
257 trap_error:
258         mflr    r3
259         b       unexpected_excep
260
261 ILLEGAL_VECTOR( 0x100 )
262 ILLEGAL_VECTOR( 0x200 )
263
264 VECTOR( 0x300, "DSI" ):
265         EXCEPTION_PREAMBLE
266         lis     r3,HA(dsi_exception)
267         addi    r3,r3,LO(dsi_exception)
268         mtctr   r3
269         bctrl
270         b       exception_return
271
272 VECTOR( 0x400, "ISI" ):
273         EXCEPTION_PREAMBLE
274         lis     r3,HA(isi_exception)
275         addi    r3,r3,LO(isi_exception)
276         mtctr   r3
277         bctrl
278         b       exception_return
279
280         ILLEGAL_VECTOR( 0x500 )
281         ILLEGAL_VECTOR( 0x600 )
282         ILLEGAL_VECTOR( 0x700 )
283
284 VECTOR( 0x800, "FPU" ):
285         mtsprg1 r3
286         mfsrr1  r3
287         ori     r3,r3,0x2000
288         mtsrr1  r3
289         mfsprg1 r3
290         rfi
291
292 ILLEGAL_VECTOR( 0x900 )
293 ILLEGAL_VECTOR( 0xa00 )
294 ILLEGAL_VECTOR( 0xb00 )
295 ILLEGAL_VECTOR( 0xc00 )
296 ILLEGAL_VECTOR( 0xd00 )
297 ILLEGAL_VECTOR( 0xe00 )
298 ILLEGAL_VECTOR( 0xf00 )
299 ILLEGAL_VECTOR( 0xf20 )
300 ILLEGAL_VECTOR( 0x1000 )
301 ILLEGAL_VECTOR( 0x1100 )
302 ILLEGAL_VECTOR( 0x1200 )
303 ILLEGAL_VECTOR( 0x1300 )
304 ILLEGAL_VECTOR( 0x1400 )
305 ILLEGAL_VECTOR( 0x1500 )
306 ILLEGAL_VECTOR( 0x1600 )
307 ILLEGAL_VECTOR( 0x1700 )
308
309 GLOBL(__vectors_end):
310
311
312 #define CACHE_LINE_SIZE         32
313 #define LG_CACHE_LINE_SIZE      5
314
315 /* flush_icache_range( unsigned long start, unsigned long stop) */
316 GLOBL(flush_icache_range):
317         li      r5,CACHE_LINE_SIZE-1
318         andc    r3,r3,r5
319         subf    r4,r3,r4
320         add     r4,r4,r5
321         srwi.   r4,r4,LG_CACHE_LINE_SIZE
322         beqlr
323         mtctr   r4
324         mr      r6,r3
325 1:      dcbst   0,r3
326         addi    r3,r3,CACHE_LINE_SIZE
327         bdnz    1b
328         sync                            /* wait for dcbst's to get to ram */
329         mtctr   r4
330 2:      icbi    0,r6
331         addi    r6,r6,CACHE_LINE_SIZE
332         bdnz    2b
333         sync                            /* additional sync needed on g4 */
334         isync
335         blr