These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / openbios / arch / sparc64 / call-client.S
1 #include "cpustate.h"
2
3         .globl  sparc64_of_client_interface, client_tba
4
5
6 /*
7  * SAVE_WINDOW_STATE and RESTORE_WINDOW_STATE are used to ensure
8  * that the CPU window state is preserved across CIF calls. This is
9  * to workaround a *BSD restriction that window fill/spill traps must
10  * be minimised during trap table takeover, and likely emulates the
11  * behaviour of OBP.
12  */
13
14         .data
15         .align  8
16
17 client_stack:
18         .xword  0
19 client_tba:
20         .xword  0
21 client_window:
22         .skip   2048
23
24
25         .text
26         .align  4
27         .register %g2, #scratch
28         .register %g3, #scratch
29         .register %g6, #scratch
30         .register %g7, #scratch
31 /*
32         make some more space on stack since linux kernel only provides 128 bytes
33         without memory to spill registers (used by gcc in -O0 mode)
34 */
35
36 sparc64_of_client_interface:
37
38         /* Save globals on callers stack */
39         add     %sp, -248, %sp
40
41         stx     %g1, [%sp + 2047 + 192]
42         stx     %g2, [%sp + 2047 + 200]
43         stx     %g3, [%sp + 2047 + 208]
44         stx     %g4, [%sp + 2047 + 216]
45         stx     %g5, [%sp + 2047 + 224]
46         stx     %g6, [%sp + 2047 + 232]
47         stx     %g7, [%sp + 2047 + 240]
48
49         /* Save client trap table */
50         setx    client_tba, %g6, %g7
51         rdpr    %tba, %g6
52         stx     %g6, [%g7]
53
54         /* Save existing stack */
55         setx    client_stack, %g6, %g7
56         stx     %sp, [%g7]
57
58         /* Save windows */
59         setx    _fcstack_ptr, %g6, %g7
60         ldx     [%g7], %g1
61         add     %g1, -CONTEXT_STATE_SIZE, %g1
62         stx     %g1, [%g7]
63         
64         SAVE_CPU_WINDOW_STATE(cif)
65
66         /* Move to OpenBIOS context stack */
67         setx    _fcstack_ptr, %g6, %g7
68         ldx     [%g7], %g6
69         setx    CONTEXT_STACK_SIZE, %g4, %g5
70         sub     %g6, %g5, %g6
71         stx     %g6, [%g7]
72         
73         setx    - 2047 - 192, %g6, %g7
74         add     %g1, %g7, %g7
75         mov     %g7, %sp
76
77         /* Call client inteface */
78         call of_client_interface
79          ldx    [%g1 + 0x30], %o0
80
81         /* Restore windows */
82         setx    _fcstack_ptr, %g6, %g7
83         ldx     [%g7], %g1
84         setx    CONTEXT_STACK_SIZE, %g4, %g5
85         add     %g1, %g5, %g1
86         stx     %g1, [%g7]
87         
88         /* Return value */
89         stx     %o0, [%g1 + 0x30]
90         
91         RESTORE_CPU_WINDOW_STATE(cif)
92         
93         add     %g1, CONTEXT_STATE_SIZE, %g1
94         setx    _fcstack_ptr, %g6, %g7
95         stx     %g1, [%g7]
96         
97         /* Restore stack */
98         setx    client_stack, %g6, %g7
99         ldx     [%g7], %sp
100
101         /* Restore client trap table */
102         setx    client_tba, %g6, %g7
103         ldx     [%g7], %g6
104         wrpr    %g6, %tba
105
106         /* Restore globals */
107         ldx     [%sp + 2047 + 192], %g1
108         ldx     [%sp + 2047 + 200], %g2
109         ldx     [%sp + 2047 + 208], %g3
110         ldx     [%sp + 2047 + 216], %g4
111         ldx     [%sp + 2047 + 224], %g5
112         ldx     [%sp + 2047 + 232], %g6
113         ldx     [%sp + 2047 + 240], %g7
114
115         add     %sp, 248, %sp
116
117         jmp     %o7+8
118          nop