Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / arch / sparc64 / switch.S
1 #include "pstate.h"
2 #include <asm/asi.h>
3 #define ASI_BP ASI_M_BYPASS
4 #define REGWIN_SZ   0x40
5
6         .globl  __switch_context, __switch_context_nosave, __exit_context, halt
7
8         .text
9         .align  4
10         .register %g2, #scratch
11         .register %g3, #scratch
12         .register %g6, #scratch
13         .register %g7, #scratch
14
15 /*
16  * Switch execution context
17  * This saves registers in the stack, then
18  * switches the stack, and restores everything from the new stack.
19  * This function takes no argument. New stack pointer is
20  * taken from global variable __context, and old stack pointer
21  * is also saved to __context. This way we can just jump to
22  * this routine to get back to the original context.
23  */
24
25 /* XXX: totally bogus for sparc, need to save and restore all windows */
26 __switch_context:
27
28         /* make sure caller's windows are on caller's stack */
29         flushw;
30
31         /* Save everything in current stack */
32
33         setx    __context, %g2, %g1
34         stx     %g3, [%g1 + 24]
35         stx     %g4, [%g1 + 32]
36         stx     %g5, [%g1 + 40]
37         stx     %g6, [%g1 + 48]
38         stx     %g7, [%g1 + 56]
39
40         stx     %o0, [%g1 + 64]
41         stx     %o1, [%g1 + 72]
42         stx     %o2, [%g1 + 80]
43         stx     %o3, [%g1 + 88]
44         stx     %o4, [%g1 + 96]
45         stx     %o5, [%g1 + 104]
46         stx     %o6, [%g1 + 112]
47         stx     %o7, [%g1 + 120]
48
49         stx     %l0, [%g1 + 128]
50         stx     %l1, [%g1 + 136]
51         stx     %l2, [%g1 + 144]
52         stx     %l3, [%g1 + 152]
53         stx     %l4, [%g1 + 160]
54         stx     %l5, [%g1 + 168]
55         stx     %l6, [%g1 + 176]
56         stx     %l7, [%g1 + 184]
57
58         stx     %i0, [%g1 + 192]
59         stx     %i1, [%g1 + 200]
60         stx     %i2, [%g1 + 208]
61         stx     %i3, [%g1 + 216]
62         stx     %i4, [%g1 + 224]
63         stx     %i5, [%g1 + 232]
64         stx     %i6, [%g1 + 240]
65         stx     %i7, [%g1 + 248]
66
67 __switch_context_nosave:
68         /* Interrupts are not allowed... */
69         /* make sure caller's windows are on caller's stack */
70         flushw
71         /* Load all registers
72          */
73         setx    __context, %g2, %g1
74         ldx     [%g1], %g1
75         ldx     [%g1 + 16], %g2
76         ldx     [%g1 + 24], %g3
77         ldx     [%g1 + 32], %g4
78         ldx     [%g1 + 40], %g5
79         ldx     [%g1 + 48], %g6
80         ldx     [%g1 + 56], %g7
81
82         ldx     [%g1 + 64], %o0
83         ldx     [%g1 + 72], %o1
84         ldx     [%g1 + 80], %o2
85         ldx     [%g1 + 88], %o3
86         ldx     [%g1 + 96], %o4
87         ldx     [%g1 + 104], %o5
88         ldx     [%g1 + 112], %o6
89         ldx     [%g1 + 120], %o7
90
91         ldx     [%g1 + 128], %l0
92         ldx     [%g1 + 136], %l1
93         ldx     [%g1 + 144], %l2
94         ldx     [%g1 + 152], %l3
95         ldx     [%g1 + 160], %l4
96         ldx     [%g1 + 168], %l5
97         ldx     [%g1 + 176], %l6
98         ldx     [%g1 + 184], %l7
99
100         ldx     [%g1 + 192], %i0
101         ldx     [%g1 + 200], %i1
102         ldx     [%g1 + 208], %i2
103         ldx     [%g1 + 216], %i3
104         ldx     [%g1 + 224], %i4
105         ldx     [%g1 + 232], %i5
106         ldx     [%g1 + 240], %i6
107         ldx     [%g1 + 248], %i7
108
109         ldx     [%g1 + 256], %g1
110         /* Finally, load new %pc */
111         jmp     %g1
112          clr    %g1
113
114 __exit_context:
115         /* Get back to the original context */
116         call    __switch_context
117          nop
118
119         /* We get here if the other context attempt to switch to this
120          * dead context. This should not happen. */
121
122 halt:
123         b       halt
124          nop