00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "cell/common.h"
00026 #include "spu_main.h"
00027 #include "spu_dcache.h"
00028
00029 #define CACHELINE_LOG2SIZE 7
00030 #define LINE_SIZE (1U << 7)
00031 #define ALIGN_MASK (~(LINE_SIZE - 1))
00032
00033 #define CACHE_NAME data
00034 #define CACHED_TYPE qword
00035 #define CACHE_TYPE CACHE_TYPE_RO
00036 #define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0)
00037 #define CACHE_LOG2NNWAY 2
00038 #define CACHE_LOG2NSETS 6
00039
00040 #include <cache-api.h>
00041
00042
00043
00044 #undef CACHE_NWAY
00045 #undef CACHE_NSETS
00046 #define CACHE_NAME data
00047 #define CACHE_NWAY 4
00048 #define CACHE_NSETS (1U << 6)
00049
00050
00062 void
00063 spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size)
00064 {
00065 const int shift = ea & 0x0f;
00066 const unsigned read_size = ROUNDUP16(size + shift);
00067 const unsigned last_read = ROUNDUP16(ea + size);
00068 const qword *const last_write = dst + (ROUNDUP16(size) / 16);
00069 unsigned i;
00070
00071
00072 if (shift == 0) {
00073
00074
00075 for (i = 0; i < size; i += 16) {
00076 *(dst++) = cache_rd(data, ea + i);
00077 }
00078 } else {
00079 qword hi;
00080
00081
00082
00083
00084
00085
00086
00087 ea &= ~0x0f;
00088 hi = cache_rd(data, ea);
00089 for (i = 16; i < read_size; i += 16) {
00090 qword lo = cache_rd(data, ea + i);
00091
00092 *(dst++) = si_or((qword) spu_slqwbyte(hi, shift),
00093 (qword) spu_rlmaskqwbyte(lo, shift - 16));
00094 hi = lo;
00095 }
00096
00097 if (dst != last_write) {
00098 *(dst++) = si_or((qword) spu_slqwbyte(hi, shift), si_il(0));
00099 }
00100 }
00101
00102 ASSERT((ea + i) == last_read);
00103 ASSERT(dst == last_write);
00104 }
00105
00106
00110 void
00111 spu_dcache_mark_dirty(unsigned ea, unsigned size)
00112 {
00113 unsigned i;
00114 const unsigned aligned_start = (ea & ALIGN_MASK);
00115 const unsigned aligned_end = (ea + size + (LINE_SIZE - 1))
00116 & ALIGN_MASK;
00117
00118
00119 for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) {
00120 const unsigned entry = __cache_dir[i];
00121 const unsigned addr = entry & ~0x0f;
00122
00123 __cache_dir[i] = ((addr >= aligned_start) && (addr < aligned_end))
00124 ? (entry & ~CACHELINE_VALID) : entry;
00125 }
00126 }
00127
00128
00132 void
00133 spu_dcache_report(void)
00134 {
00135 #ifdef CACHE_STATS
00136 if (spu.init.id == 0) {
00137 printf("SPU 0: Texture cache report:\n");
00138 cache_pr_stats(data);
00139 }
00140 #endif
00141 }
00142
00143