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