1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#ifndef LS_SIZE
29#define LS_SIZE 0x40000
30#endif
31
32typedef unsigned int u32;
33typedef unsigned long long u64;
34
35#include <spu_intrinsics.h>
36#include <asm/spu_csa.h>
37#include "spu_utils.h"
38
39static inline void save_event_mask(void)
40{
41 unsigned int offset;
42
43
44
45
46 offset = LSCSA_QW_OFFSET(event_mask);
47 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventMask);
48}
49
50static inline void save_tag_mask(void)
51{
52 unsigned int offset;
53
54
55
56
57 offset = LSCSA_QW_OFFSET(tag_mask);
58 regs_spill[offset].slot[0] = spu_readch(MFC_RdTagMask);
59}
60
61static inline void save_upper_240kb(addr64 lscsa_ea)
62{
63 unsigned int ls = 16384;
64 unsigned int list = (unsigned int)&dma_list[0];
65 unsigned int size = sizeof(dma_list);
66 unsigned int tag_id = 0;
67 unsigned int cmd = 0x24;
68
69
70
71
72
73 spu_writech(MFC_LSA, ls);
74 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
75 spu_writech(MFC_EAL, list);
76 spu_writech(MFC_Size, size);
77 spu_writech(MFC_TagID, tag_id);
78 spu_writech(MFC_Cmd, cmd);
79}
80
81static inline void save_fpcr(void)
82{
83
84 unsigned int offset;
85
86
87
88
89
90 offset = LSCSA_QW_OFFSET(fpcr);
91 regs_spill[offset].v = spu_mffpscr();
92}
93
94static inline void save_decr(void)
95{
96 unsigned int offset;
97
98
99
100
101
102 offset = LSCSA_QW_OFFSET(decr);
103 regs_spill[offset].slot[0] = spu_readch(SPU_RdDec);
104}
105
106static inline void save_srr0(void)
107{
108 unsigned int offset;
109
110
111
112
113
114 offset = LSCSA_QW_OFFSET(srr0);
115 regs_spill[offset].slot[0] = spu_readch(SPU_RdSRR0);
116}
117
118static inline void spill_regs_to_mem(addr64 lscsa_ea)
119{
120 unsigned int ls = (unsigned int)®s_spill[0];
121 unsigned int size = sizeof(regs_spill);
122 unsigned int tag_id = 0;
123 unsigned int cmd = 0x20;
124
125
126
127
128
129 spu_writech(MFC_LSA, ls);
130 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
131 spu_writech(MFC_EAL, lscsa_ea.ui[1]);
132 spu_writech(MFC_Size, size);
133 spu_writech(MFC_TagID, tag_id);
134 spu_writech(MFC_Cmd, cmd);
135}
136
137static inline void enqueue_sync(addr64 lscsa_ea)
138{
139 unsigned int tag_id = 0;
140 unsigned int cmd = 0xCC;
141
142
143
144
145 spu_writech(MFC_TagID, tag_id);
146 spu_writech(MFC_Cmd, cmd);
147}
148
149static inline void save_complete(void)
150{
151
152
153
154
155
156 spu_stop(SPU_SAVE_COMPLETE);
157}
158
159
160
161
162
163
164
165
166
167
168int main()
169{
170 addr64 lscsa_ea;
171
172 lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1);
173 lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2);
174
175
176 save_event_mask();
177 save_tag_mask();
178 set_event_mask();
179 set_tag_mask();
180 build_dma_list(lscsa_ea);
181 save_upper_240kb(lscsa_ea);
182
183 save_fpcr();
184 save_decr();
185 save_srr0();
186 enqueue_putllc(lscsa_ea);
187 spill_regs_to_mem(lscsa_ea);
188 enqueue_sync(lscsa_ea);
189 set_tag_update();
190 read_tag_status();
191 read_llar_status();
192 save_complete();
193
194 return 0;
195}
196