[POWERPC] spufs: set SPU_CONTEXT_SWITCH_PENDING before synchronising SPU irqs
[linux-2.6] / arch / powerpc / platforms / cell / spufs / spu_restore_crt0.S
1 /*
2  * crt0_r.S: Entry function for SPU-side context restore.
3  *
4  * Copyright (C) 2005 IBM
5  *
6  * Entry and exit function for SPU-side of the context restore
7  * sequence.  Sets up an initial stack frame, then branches to
8  * 'main'.  On return, restores all 128 registers from the LSCSA
9  * and exits.
10  *
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26
27 #include <asm/spu_csa.h>
28
29 .data
30 .align 7
31 .globl regs_spill
32 regs_spill:
33 .space SIZEOF_SPU_SPILL_REGS, 0x0
34
35 .text
36 .global _start
37 _start:
38         /* Initialize the stack pointer to point to 16368
39          * (16kb-16). The back chain pointer is initialized
40          * to NULL.
41          */
42         il      $0, 0
43         il      $SP, 16368
44         stqd    $0, 0($SP)
45
46         /* Allocate a minimum stack frame for the called main.
47          * This is needed so that main has a place to save the
48          * link register when it calls another function.
49          */
50         stqd    $SP, -160($SP)
51         ai      $SP, $SP, -160
52
53         /* Call the program's main function. */
54         brsl    $0, main
55
56 .global exit
57 .global _exit
58 exit:
59 _exit:
60         /* SPU Context Restore, Step 5: Restore the remaining 112 GPRs. */
61         ila     $3, regs_spill + 256
62 restore_regs:
63         lqr     $4, restore_reg_insts
64 restore_reg_loop:
65         ai      $4, $4, 4
66         .balignl 16, 0x40200000
67 restore_reg_insts:       /* must be quad-word aligned. */
68         lqd     $16, 0($3)
69         lqd     $17, 16($3)
70         lqd     $18, 32($3)
71         lqd     $19, 48($3)
72         andi    $5, $4, 0x7F
73         stqr    $4, restore_reg_insts
74         ai      $3, $3, 64
75         brnz    $5, restore_reg_loop
76
77         /* SPU Context Restore Step 17: Restore the first 16 GPRs. */
78         lqa $0, regs_spill + 0
79         lqa $1, regs_spill + 16
80         lqa $2, regs_spill + 32
81         lqa $3, regs_spill + 48
82         lqa $4, regs_spill + 64
83         lqa $5, regs_spill + 80
84         lqa $6, regs_spill + 96
85         lqa $7, regs_spill + 112
86         lqa $8, regs_spill + 128
87         lqa $9, regs_spill + 144
88         lqa $10, regs_spill + 160
89         lqa $11, regs_spill + 176
90         lqa $12, regs_spill + 192
91         lqa $13, regs_spill + 208
92         lqa $14, regs_spill + 224
93         lqa $15, regs_spill + 240
94
95         /* Under normal circumstances, the 'exit' function
96          * terminates with 'stop SPU_RESTORE_COMPLETE',
97          * indicating that the SPU-side restore code has
98          * completed.
99          *
100          * However it is possible that instructions immediately
101          * following the 'stop 0x3ffc' have been modified at run
102          * time so as to recreate the exact SPU_Status settings
103          * from the application, e.g. illegal instruciton, halt,
104          * etc.
105          */
106 .global exit_fini
107 .global _exit_fini
108 exit_fini:
109 _exit_fini:
110         stop    SPU_RESTORE_COMPLETE
111         stop    0
112         stop    0
113         stop    0
114
115         /* Pad the size of this crt0.o to be multiple of 16 bytes. */
116 .balignl 16, 0x0