0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LS_SIZE
0015 #define LS_SIZE 0x40000
0016 #endif
0017
0018 typedef unsigned int u32;
0019 typedef unsigned long long u64;
0020
0021 #include <spu_intrinsics.h>
0022 #include <asm/spu_csa.h>
0023 #include "spu_utils.h"
0024
0025 static inline void save_event_mask(void)
0026 {
0027 unsigned int offset;
0028
0029
0030
0031
0032 offset = LSCSA_QW_OFFSET(event_mask);
0033 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventMask);
0034 }
0035
0036 static inline void save_tag_mask(void)
0037 {
0038 unsigned int offset;
0039
0040
0041
0042
0043 offset = LSCSA_QW_OFFSET(tag_mask);
0044 regs_spill[offset].slot[0] = spu_readch(MFC_RdTagMask);
0045 }
0046
0047 static inline void save_upper_240kb(addr64 lscsa_ea)
0048 {
0049 unsigned int ls = 16384;
0050 unsigned int list = (unsigned int)&dma_list[0];
0051 unsigned int size = sizeof(dma_list);
0052 unsigned int tag_id = 0;
0053 unsigned int cmd = 0x24;
0054
0055
0056
0057
0058
0059 spu_writech(MFC_LSA, ls);
0060 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
0061 spu_writech(MFC_EAL, list);
0062 spu_writech(MFC_Size, size);
0063 spu_writech(MFC_TagID, tag_id);
0064 spu_writech(MFC_Cmd, cmd);
0065 }
0066
0067 static inline void save_fpcr(void)
0068 {
0069
0070 unsigned int offset;
0071
0072
0073
0074
0075
0076 offset = LSCSA_QW_OFFSET(fpcr);
0077 regs_spill[offset].v = spu_mffpscr();
0078 }
0079
0080 static inline void save_decr(void)
0081 {
0082 unsigned int offset;
0083
0084
0085
0086
0087
0088 offset = LSCSA_QW_OFFSET(decr);
0089 regs_spill[offset].slot[0] = spu_readch(SPU_RdDec);
0090 }
0091
0092 static inline void save_srr0(void)
0093 {
0094 unsigned int offset;
0095
0096
0097
0098
0099
0100 offset = LSCSA_QW_OFFSET(srr0);
0101 regs_spill[offset].slot[0] = spu_readch(SPU_RdSRR0);
0102 }
0103
0104 static inline void spill_regs_to_mem(addr64 lscsa_ea)
0105 {
0106 unsigned int ls = (unsigned int)®s_spill[0];
0107 unsigned int size = sizeof(regs_spill);
0108 unsigned int tag_id = 0;
0109 unsigned int cmd = 0x20;
0110
0111
0112
0113
0114
0115 spu_writech(MFC_LSA, ls);
0116 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
0117 spu_writech(MFC_EAL, lscsa_ea.ui[1]);
0118 spu_writech(MFC_Size, size);
0119 spu_writech(MFC_TagID, tag_id);
0120 spu_writech(MFC_Cmd, cmd);
0121 }
0122
0123 static inline void enqueue_sync(addr64 lscsa_ea)
0124 {
0125 unsigned int tag_id = 0;
0126 unsigned int cmd = 0xCC;
0127
0128
0129
0130
0131 spu_writech(MFC_TagID, tag_id);
0132 spu_writech(MFC_Cmd, cmd);
0133 }
0134
0135 static inline void save_complete(void)
0136 {
0137
0138
0139
0140
0141
0142 spu_stop(SPU_SAVE_COMPLETE);
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 int main()
0155 {
0156 addr64 lscsa_ea;
0157
0158 lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1);
0159 lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2);
0160
0161
0162 save_event_mask();
0163 save_tag_mask();
0164 set_event_mask();
0165 set_tag_mask();
0166 build_dma_list(lscsa_ea);
0167 save_upper_240kb(lscsa_ea);
0168
0169 save_fpcr();
0170 save_decr();
0171 save_srr0();
0172 enqueue_putllc(lscsa_ea);
0173 spill_regs_to_mem(lscsa_ea);
0174 enqueue_sync(lscsa_ea);
0175 set_tag_update();
0176 read_tag_status();
0177 read_llar_status();
0178 save_complete();
0179
0180 return 0;
0181 }