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
32regs_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
58exit:
59_exit:
60	/* SPU Context Restore, Step 5: Restore the remaining 112 GPRs. */
61	ila     $3, regs_spill + 256
62restore_regs:
63	lqr     $4, restore_reg_insts
64restore_reg_loop:
65	ai      $4, $4, 4
66	.balignl 16, 0x40200000
67restore_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
108exit_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
117