2 * (C) Copyright IBM Corporation 2008
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include "cell/common.h"
27 #include "spu_dcache.h"
29 #define CACHELINE_LOG2SIZE 7
30 #define LINE_SIZE (1U << 7)
31 #define ALIGN_MASK (~(LINE_SIZE - 1))
33 #define CACHE_NAME data
34 #define CACHED_TYPE qword
35 #define CACHE_TYPE CACHE_TYPE_RO
36 #define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0)
37 #define CACHE_LOG2NNWAY 2
38 #define CACHE_LOG2NSETS 6
42 #include <cache-api.h>
44 /* Yes folks, this is ugly.
48 #define CACHE_NAME data
50 #define CACHE_NSETS (1U << 6)
54 * Fetch between arbitrary number of bytes from an unaligned address
56 * \param dst Destination data buffer
57 * \param ea Main memory effective address of source data
58 * \param size Number of bytes to read
61 * As is hinted by the type of the \c dst pointer, this function writes
62 * multiples of 16-bytes.
65 spu_dcache_fetch_unaligned(qword
*dst
, unsigned ea
, unsigned size
)
67 const int shift
= ea
& 0x0f;
68 const unsigned read_size
= ROUNDUP16(size
+ shift
);
69 const unsigned last_read
= ROUNDUP16(ea
+ size
);
70 const qword
*const last_write
= dst
+ (ROUNDUP16(size
) / 16);
75 /* Data is already aligned. Fetch directly into the destination buffer.
77 for (i
= 0; i
< size
; i
+= 16) {
78 *(dst
++) = cache_rd(data
, ea
+ i
);
84 /* Please exercise extreme caution when modifying this code. This code
85 * must not read past the end of the page containing the source data,
86 * and it must not write more than ((size + 15) / 16) qwords to the
90 hi
= cache_rd(data
, ea
);
91 for (i
= 16; i
< read_size
; i
+= 16) {
92 qword lo
= cache_rd(data
, ea
+ i
);
94 *(dst
++) = si_or((qword
) spu_slqwbyte(hi
, shift
),
95 (qword
) spu_rlmaskqwbyte(lo
, shift
- 16));
99 if (dst
!= last_write
) {
100 *(dst
++) = si_or((qword
) spu_slqwbyte(hi
, shift
), si_il(0));
104 ASSERT((ea
+ i
) == last_read
);
105 ASSERT(dst
== last_write
);
110 * Notify the cache that a range of main memory may have been modified
113 spu_dcache_mark_dirty(unsigned ea
, unsigned size
)
116 const unsigned aligned_start
= (ea
& ALIGN_MASK
);
117 const unsigned aligned_end
= (ea
+ size
+ (LINE_SIZE
- 1))
121 for (i
= 0; i
< (CACHE_NWAY
* CACHE_NSETS
); i
++) {
122 const unsigned entry
= __cache_dir
[i
];
123 const unsigned addr
= entry
& ~0x0f;
125 __cache_dir
[i
] = ((addr
>= aligned_start
) && (addr
< aligned_end
))
126 ? (entry
& ~CACHELINE_VALID
) : entry
;
132 * Print cache utilization report
135 spu_dcache_report(void)
138 if (spu
.init
.id
== 0) {
139 printf("SPU 0: Texture cache report:\n");
140 cache_pr_stats(data
);