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
39 #include <cache-api.h>
41 /* Yes folks, this is ugly.
45 #define CACHE_NAME data
47 #define CACHE_NSETS (1U << 6)
51 * Fetch between arbitrary number of bytes from an unaligned address
54 spu_dcache_fetch_unaligned(qword
*dst
, unsigned ea
, unsigned size
)
56 const int shift
= ea
& 0x0f;
57 const unsigned aligned_start_ea
= ea
& ~0x0f;
58 const unsigned aligned_end_ea
= ROUNDUP16(ea
+ size
);
59 const unsigned num_entries
= (aligned_end_ea
- aligned_start_ea
) / 16;
64 /* Data is already aligned. Fetch directly into the destination buffer.
66 for (i
= 0; i
< num_entries
; i
++) {
67 dst
[i
] = cache_rd(data
, ea
+ (i
* 16));
70 qword tmp
[2] ALIGN16_ATTRIB
;
73 tmp
[0] = cache_rd(data
, (ea
& ~0x0f));
74 for (i
= 0; i
< (num_entries
& ~1); i
++) {
75 const unsigned curr
= i
& 1;
76 const unsigned next
= curr
^ 1;
78 tmp
[next
] = cache_rd(data
, (ea
& ~0x0f) + (next
* 16));
80 dst
[i
] = si_or((qword
) spu_slqwbyte(tmp
[curr
], shift
),
81 (qword
) spu_rlmaskqwbyte(tmp
[next
], shift
- 16));
84 if (i
< num_entries
) {
85 dst
[i
] = si_or((qword
) spu_slqwbyte(tmp
[(i
& 1)], shift
),
93 * Notify the cache that a range of main memory may have been modified
96 spu_dcache_mark_dirty(unsigned ea
, unsigned size
)
99 const unsigned aligned_start
= (ea
& ALIGN_MASK
);
100 const unsigned aligned_end
= (ea
+ size
+ (LINE_SIZE
- 1))
104 for (i
= 0; i
< (CACHE_NWAY
* CACHE_NSETS
); i
++) {
105 const unsigned entry
= __cache_dir
[i
];
106 const unsigned addr
= entry
& ~0x0f;
108 __cache_dir
[i
] = ((addr
>= aligned_start
) && (addr
< aligned_end
))
109 ? (entry
& ~CACHELINE_VALID
) : entry
;