Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / slof / entry.S
1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12
13 #include <macros.h>
14
15 #define STACKSIZE 0x2000
16
17         #
18         # The generic exception code.
19         #
20         # Enter with GPR0 = vector, SPRG0 = saved GPR0
21         #
22
23         .section ".entry_text"
24
25 the_handler:
26         .quad   handler
27
28 eregs:
29         /* the_exception_frame is a C variable which is usually
30          * defined in $(TARG).c
31          * the_exception_frame can be accessed from paflof through
32          * the word eregs
33          * in the case an excpetion is handled paflof will read
34          * from eregs the values of all registers and print them
35          * out in the exception handler */
36         .quad   the_exception_frame
37
38 handler:
39         mtsprg 1,1      # SPRG1 = saved GPR1
40         bcl 20,31,$+4
41         mflr 1
42         ld 1,eregs-$+4(1)       # GPR1 = address of register save area
43
44         .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
45                 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
46         std \i,\i*8(1)
47         .endr           # save GPR2..GPR31
48
49         li r3, 3        // GPR3 = mode (param_1, param_2)
50         mr 4,0          // GPR4 = vector
51
52         mfsprg 0,0
53         std 0,0(1)      # save GPR0
54         mfsprg 0,1
55         std 0,8(1)      # save GPR1
56
57         cmpwi   r4, 0x900       # Decrementer interrupt
58         bne     0f
59         mfdec   r5              # Save old value of decrementer as reason
60         lis     r0,0x7fff       # Set decrementer to highest value 
61         mtdec   r0
62 0:
63         mfcr 0
64         std 0,0x100(1)
65         mfxer 0
66         std 0,0x108(1)
67         mfsprg 0,3      # save lr       
68         std 0,0x110(1)
69         mfsprg 0,2      # save ctr      
70         std 0,0x118(1)
71         mfsrr0 0
72         std 0,0x120(1)
73         mfsrr1 0
74         std 0,0x128(1)
75         mfdar 0
76         std 0,0x130(1)
77         mfdsisr 0
78         std 0,0x138(1)  # save special regs
79
80         bcl     20, 31, over
81 base:
82         .align  3
83 .the_system_stack:
84         .quad   the_system_stack+STACKSIZE-base
85 over:
86         mflr    r2                              /* gpr 2 is the base */
87         ld      r1, .the_system_stack-base(r2)  /* load stack pointer */
88         add     r1, r1, r2                      /* add base */
89         li      r0, 0
90         stdu    r0, -0x10(r1)
91         stdu    r1, -0x100(r1)
92
93         lis 2,engine@ha
94         ld 0,engine@l(2) # set up entry
95         mtsrr0  0
96                 
97         ld 2,8+engine@l(2) # set up TOC pointer
98
99         rfid
100 #       b .engine       # ...and run!
101
102
103
104         #
105         # Swap non-volatile client interface regs, plus GPR3..GPR7.
106         #
107
108 swap_ci_regs:
109         /* save lr */
110         mflr    r0
111         /* let's find out where our client stack is */
112         bcl     20, 31, client_over
113 client_base:
114         .align  3
115 .the_client_frame:
116         .quad   the_client_frame-client_base
117 client_over:
118         mflr    r8                              /* gpr 2 is the client_base */
119         mtlr    r0                              /* restore the original lr */
120         ld      r0, .the_client_frame-client_base(r8)
121         add     r8, r0, r8                      /* add the client_base */
122         /* r8 now contains the address of the_client_frame */
123
124         .irp i, 1,2,3,4,5,6,7, \
125                 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
126         ld 0,\i*8(8)
127         std \i,\i*8(8)
128         mr \i,0
129         .endr           # swap GPR1..7, GPR13..31
130
131         ld 0,0x100(8)
132         mfcr 9
133         mtcrf 0xff,0
134         std 9,0x100(8)  # swap CR
135
136         ld 0,0x128(8)
137         mfmsr 9
138         mtmsrd 0
139         sync
140         isync
141         std 9,0x128(8)  # swap MSR
142
143         blr
144
145         #
146         # Entry point for the OF client interface.
147         #
148
149         .globl client_entry_point
150         .section        ".opd","aw"
151         .align 3
152 client_entry_point:
153         .quad   .client_entry_point,.TOC.@tocbase,0
154         .previous
155         .type   .client_entry_point,@function
156         .globl  .client_entry_point
157 .client_entry_point:
158         mflr 4
159         bl swap_ci_regs # swap regs
160         mtlr 4
161         li 3, 0 # client call
162         blr     
163
164         #
165         # Start the client.
166         #
167
168         .globl call_client
169         .section        ".opd","aw"
170         .align 3
171 call_client:
172         .quad   .call_client,.TOC.@tocbase,0
173         .previous
174         .type   .call_client,@function
175         .globl  .call_client
176
177 .call_client:   # called with r3 = address, returns r3
178         mflr 4
179         mtctr 3
180         bl swap_ci_regs
181         /* Check if LE loading */
182         cmpwi 0,13,1
183         beq 0f
184         bctrl
185         b 1f
186 0:      /* handle LE */
187         mfmsr 13
188         xori  13,13,1
189         mtsrr1 13
190         mfctr 13
191         mr 12,13
192         mtsrr0 13
193         rfid
194 #if 0 /* in case we return back, still to be tested */
195         .long 0x05009f42; /* bcl 20,31,$+4   */
196         .long 0xa602c87d; /* mflr r14    */
197         .long 0x1c00ce39; /* addi r14,r14,28   */
198         .long 0xa600e07d; /* mfmsr r15    */
199         .long 0x0100ef69; /* xori r15,r15,1   */
200         .long 0xa603da7d; /* mtsrr0 r14    */
201         .long 0xa603fb7d; /* mtsrr1 r15    */
202         .long 0x2400004c; /* rfid */
203 #endif
204 1:
205         bl swap_ci_regs
206         mtlr 4
207         li 3, -1 # client app return
208         blr
209
210         .lcomm  the_system_stack, STACKSIZE, 16