Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: SS_MsyncMemory.cc | |
4 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
5 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
6 | // | |
7 | // The above named program is free software; you can redistribute it and/or | |
8 | // modify it under the terms of the GNU General Public | |
9 | // License version 2 as published by the Free Software Foundation. | |
10 | // | |
11 | // The above named program is distributed in the hope that it will be | |
12 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | // General Public License for more details. | |
15 | // | |
16 | // You should have received a copy of the GNU General Public | |
17 | // License along with this work; if not, write to the Free Software | |
18 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | // | |
20 | // ========== Copyright Header End ============================================ | |
21 | ||
22 | #ifdef MEMORY_MSYNC | |
23 | ||
24 | #include <sys/mman.h> | |
25 | #include <errno.h> | |
26 | #include <ctype.h> | |
27 | #include <stdio.h> | |
28 | #include <stdlib.h> | |
29 | #include <string.h> | |
30 | #include <assert.h> | |
31 | #include "SS_MsyncMemory.h" | |
32 | #include "SS_Strand.h" | |
33 | #include <exception.h> | |
34 | ||
35 | SS_MsyncMemory SS_MsyncMemory::memory; | |
36 | ||
37 | SS_MsyncMemory::SS_MsyncMemory()/*{{{*/ | |
38 | : | |
39 | SS_FastMemory(), | |
40 | msync_object(0), | |
41 | msync_pre_access(0), | |
42 | msync_post_access(0) | |
43 | { | |
44 | } | |
45 | /*}}}*/ | |
46 | SS_MsyncMemory::~SS_MsyncMemory()/*{{{*/ | |
47 | { | |
48 | } | |
49 | /*}}}*/ | |
50 | ||
51 | ||
52 | void SS_MsyncMemory::msync_st( uint64_t addr, uint_t size, uint64_t data )/*{{{*/ | |
53 | { | |
54 | mem_xact.paddr(addr); | |
55 | mem_xact.size(size); | |
56 | mem_xact.access(MemoryTransaction::WRITE); | |
57 | mem_xact.referenceType(MemoryTransaction::DATA); | |
58 | mem_xact.setData(data); | |
59 | ||
60 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
61 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
62 | } | |
63 | /*}}}*/ | |
64 | void SS_MsyncMemory::msync_st( uint64_t addr, uint_t size, uint64_t* data )/*{{{*/ | |
65 | { | |
66 | mem_xact.paddr(addr); | |
67 | mem_xact.size(size); | |
68 | mem_xact.access(MemoryTransaction::WRITE); | |
69 | mem_xact.referenceType(MemoryTransaction::DATA); | |
70 | ||
71 | for (uint_t i=0; size; i++, size -= 8) | |
72 | mem_xact.setData(i,data[i]); | |
73 | ||
74 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
75 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
76 | } | |
77 | /*}}}*/ | |
78 | ||
79 | uint64_t SS_MsyncMemory::msync_ld( uint64_t addr, uint_t size )/*{{{*/ | |
80 | { | |
81 | mem_xact.paddr(addr); | |
82 | mem_xact.size(size); | |
83 | mem_xact.access(MemoryTransaction::READ); | |
84 | mem_xact.referenceType(MemoryTransaction::DATA); | |
85 | ||
86 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
87 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
88 | ||
89 | return mem_xact.getData(); | |
90 | } | |
91 | /*}}}*/ | |
92 | void SS_MsyncMemory::msync_ld( uint64_t addr, uint_t size, uint64_t* data )/*{{{*/ | |
93 | { | |
94 | mem_xact.paddr(addr); | |
95 | mem_xact.size(size); | |
96 | mem_xact.access(MemoryTransaction::READ); | |
97 | mem_xact.referenceType(MemoryTransaction::DATA); | |
98 | ||
99 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
100 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
101 | ||
102 | for (uint_t i=0; size; i++, size -= 8) | |
103 | data[i]= mem_xact.getData(i); | |
104 | } | |
105 | /*}}}*/ | |
106 | ||
107 | ||
108 | ||
109 | uint32_t SS_MsyncMemory::fetch32( uint64_t addr )/*{{{*/ | |
110 | { | |
111 | if (msync_object) | |
112 | { | |
113 | mem_xact.paddr(addr); | |
114 | mem_xact.size(4); | |
115 | mem_xact.access(MemoryTransaction::READ); | |
116 | mem_xact.referenceType(MemoryTransaction::INSTR); | |
117 | ||
118 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
119 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
120 | } | |
121 | ||
122 | return SS_FastMemory::fetch32(addr); | |
123 | } | |
124 | /*}}}*/ | |
125 | void SS_MsyncMemory::fetch256( uint64_t addr, uint64_t data[4] )/*{{{*/ | |
126 | { | |
127 | if (msync_object) | |
128 | { | |
129 | mem_xact.paddr(addr); | |
130 | mem_xact.size(32); | |
131 | mem_xact.access(MemoryTransaction::READ); | |
132 | mem_xact.referenceType(MemoryTransaction::INSTR); | |
133 | ||
134 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
135 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
136 | } | |
137 | ||
138 | SS_FastMemory::fetch256(addr,data); | |
139 | } | |
140 | /*}}}*/ | |
141 | void SS_MsyncMemory::fetch512( uint64_t addr, uint64_t data[8] )/*{{{*/ | |
142 | { | |
143 | if (msync_object) | |
144 | { | |
145 | mem_xact.paddr(addr); | |
146 | mem_xact.size(64); | |
147 | mem_xact.access(MemoryTransaction::READ); | |
148 | mem_xact.referenceType(MemoryTransaction::INSTR); | |
149 | ||
150 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
151 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
152 | } | |
153 | ||
154 | SS_FastMemory::fetch512(addr,data); | |
155 | } | |
156 | /*}}}*/ | |
157 | ||
158 | void SS_MsyncMemory::st8( uint64_t addr, uint8_t data )/*{{{*/ | |
159 | { | |
160 | if (msync_object) | |
161 | msync_st(addr,1,data); | |
162 | else | |
163 | SS_FastMemory::st8(addr,data); | |
164 | } | |
165 | /*}}}*/ | |
166 | void SS_MsyncMemory::st16( uint64_t addr, uint16_t data )/*{{{*/ | |
167 | { | |
168 | if (msync_object) | |
169 | msync_st(addr,2,data); | |
170 | else | |
171 | SS_FastMemory::st16(addr,data); | |
172 | } | |
173 | /*}}}*/ | |
174 | void SS_MsyncMemory::st32( uint64_t addr, uint32_t data )/*{{{*/ | |
175 | { | |
176 | if (msync_object) | |
177 | msync_st(addr,4,data); | |
178 | else | |
179 | SS_FastMemory::st32(addr,data); | |
180 | } | |
181 | /*}}}*/ | |
182 | void SS_MsyncMemory::st64( uint64_t addr, uint64_t data )/*{{{*/ | |
183 | { | |
184 | if (msync_object) | |
185 | msync_st(addr,8,data); | |
186 | else | |
187 | SS_FastMemory::st64(addr,data); | |
188 | } | |
189 | /*}}}*/ | |
190 | void SS_MsyncMemory::st128( uint64_t addr, uint64_t data[2] )/*{{{*/ | |
191 | { | |
192 | if (msync_object) | |
193 | msync_st(addr,16,data); | |
194 | else | |
195 | { | |
196 | SS_FastMemory::st128(addr,data); | |
197 | } | |
198 | } | |
199 | /*}}}*/ | |
200 | void SS_MsyncMemory::st512( uint64_t addr, uint64_t data[8] )/*{{{*/ | |
201 | { | |
202 | if (msync_object) | |
203 | msync_st(addr,64,data); | |
204 | else | |
205 | { | |
206 | SS_FastMemory::st512(addr,data); | |
207 | } | |
208 | } | |
209 | /*}}}*/ | |
210 | ||
211 | uint8_t SS_MsyncMemory::ld8u ( uint64_t addr )/*{{{*/ | |
212 | { | |
213 | if (msync_object) | |
214 | return msync_ld(addr,1); | |
215 | else | |
216 | return SS_FastMemory::ld8u(addr); | |
217 | } | |
218 | /*}}}*/ | |
219 | int8_t SS_MsyncMemory::ld8s( uint64_t addr )/*{{{*/ | |
220 | { | |
221 | if (msync_object) | |
222 | return msync_ld(addr,1); | |
223 | else | |
224 | return SS_FastMemory::ld8s(addr); | |
225 | } | |
226 | /*}}}*/ | |
227 | uint16_t SS_MsyncMemory::ld16u( uint64_t addr )/*{{{*/ | |
228 | { | |
229 | if (msync_object) | |
230 | return msync_ld(addr,2); | |
231 | else | |
232 | return SS_FastMemory::ld16u(addr); | |
233 | } | |
234 | /*}}}*/ | |
235 | int16_t SS_MsyncMemory::ld16s( uint64_t addr )/*{{{*/ | |
236 | { | |
237 | if (msync_object) | |
238 | return msync_ld(addr,2); | |
239 | else | |
240 | return SS_FastMemory::ld16s(addr); | |
241 | } | |
242 | /*}}}*/ | |
243 | uint32_t SS_MsyncMemory::ld32u( uint64_t addr )/*{{{*/ | |
244 | { | |
245 | if (msync_object) | |
246 | return msync_ld(addr,4); | |
247 | else | |
248 | return SS_FastMemory::ld32u(addr); | |
249 | } | |
250 | /*}}}*/ | |
251 | int32_t SS_MsyncMemory::ld32s( uint64_t addr )/*{{{*/ | |
252 | { | |
253 | if (msync_object) | |
254 | return msync_ld(addr,4); | |
255 | else | |
256 | return SS_FastMemory::ld32s(addr); | |
257 | } | |
258 | /*}}}*/ | |
259 | uint64_t SS_MsyncMemory::ld64( uint64_t addr )/*{{{*/ | |
260 | { | |
261 | if (msync_object) | |
262 | return msync_ld(addr,8); | |
263 | else | |
264 | return SS_FastMemory::ld64(addr); | |
265 | } | |
266 | /*}}}*/ | |
267 | void SS_MsyncMemory::ld128( uint64_t addr, uint64_t data[2] ) /*{{{*/ | |
268 | { | |
269 | if (msync_object) | |
270 | msync_ld(addr,16,data); | |
271 | else | |
272 | { | |
273 | SS_FastMemory::ld128(addr,data); | |
274 | } | |
275 | } | |
276 | /*}}}*/ | |
277 | void SS_MsyncMemory::ld256( uint64_t addr, uint64_t data[4] )/*{{{*/ | |
278 | { | |
279 | if (msync_object) | |
280 | msync_ld(addr,32,data); | |
281 | else | |
282 | { | |
283 | SS_FastMemory::ld256(addr,data); | |
284 | } | |
285 | } | |
286 | /*}}}*/ | |
287 | void SS_MsyncMemory::ld512( uint64_t addr, uint64_t data[8] )/*{{{*/ | |
288 | { | |
289 | if (msync_object) | |
290 | msync_ld(addr,64,data); | |
291 | else | |
292 | { | |
293 | SS_FastMemory::ld512(addr,data); | |
294 | } | |
295 | } | |
296 | /*}}}*/ | |
297 | ||
298 | void SS_MsyncMemory::st64partial( uint64_t addr, uint64_t data, uint64_t mask ) /*{{{*/ | |
299 | { | |
300 | if (msync_object) | |
301 | { | |
302 | uint64_t temp = peek64(addr); | |
303 | ||
304 | if (mask < 0x100) | |
305 | { | |
306 | uint64_t data_mask = 0x0; | |
307 | for(int i=0; i < 0x8; i++) | |
308 | if((mask >> i) & 0x1) | |
309 | data_mask |= (0xffULL << (0x8 * i)); | |
310 | data = (temp & ~data_mask) | (data & data_mask); | |
311 | } | |
312 | st64(addr,data); | |
313 | } | |
314 | else | |
315 | SS_FastMemory::st64partial(addr,data,mask); | |
316 | } | |
317 | /*}}}*/ | |
318 | ||
319 | void SS_MsyncMemory::ld128atomic( uint64_t addr, uint64_t data[2] )/*{{{*/ | |
320 | { | |
321 | if (msync_object && (msync_help == NONE)) | |
322 | msync_ld(addr,16,data); | |
323 | else | |
324 | { | |
325 | SS_FastMemory::ld128atomic(addr,data); | |
326 | } | |
327 | } | |
328 | /*}}}*/ | |
329 | ||
330 | uint8_t SS_MsyncMemory::ldstub( uint64_t addr )/*{{{*/ | |
331 | { | |
332 | if (msync_object) | |
333 | { | |
334 | mem_xact.referenceType(MemoryTransaction::DATA); | |
335 | mem_xact.paddr(addr); | |
336 | mem_xact.size(1); | |
337 | mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC); | |
338 | ||
339 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
340 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
341 | ||
342 | uint8_t data = mem_xact.getData(); | |
343 | mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC); | |
344 | mem_xact.setData(0xff); | |
345 | ||
346 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
347 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
348 | ||
349 | return data; | |
350 | } | |
351 | else | |
352 | return SS_FastMemory::ldstub( addr ); | |
353 | } | |
354 | /*}}}*/ | |
355 | uint32_t SS_MsyncMemory::swap( uint64_t addr, uint32_t rd )/*{{{*/ | |
356 | { | |
357 | if (msync_object) | |
358 | { | |
359 | mem_xact.referenceType(MemoryTransaction::DATA); | |
360 | mem_xact.paddr(addr); | |
361 | mem_xact.size(4); | |
362 | mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC); | |
363 | ||
364 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
365 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
366 | ||
367 | uint32_t data = mem_xact.getData(); | |
368 | mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC); | |
369 | mem_xact.setData(rd); | |
370 | ||
371 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
372 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
373 | ||
374 | return data; | |
375 | } | |
376 | else | |
377 | return SS_FastMemory::swap( addr,rd ); | |
378 | } | |
379 | /*}}}*/ | |
380 | uint64_t SS_MsyncMemory::casx( uint64_t addr, uint64_t rd, uint64_t rs2 )/*{{{*/ | |
381 | { | |
382 | if (msync_object) | |
383 | { | |
384 | mem_xact.referenceType(MemoryTransaction::DATA); | |
385 | mem_xact.paddr(addr); | |
386 | mem_xact.size(8); | |
387 | mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC); | |
388 | ||
389 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
390 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
391 | ||
392 | uint64_t data = mem_xact.getData(); | |
393 | if (data == rs2) | |
394 | { | |
395 | mem_xact.setData(rd); | |
396 | ||
397 | mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC); | |
398 | ||
399 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
400 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
401 | } | |
402 | return data; | |
403 | } | |
404 | else | |
405 | return SS_FastMemory::casx( addr,rd ,rs2); | |
406 | } | |
407 | /*}}}*/ | |
408 | uint32_t SS_MsyncMemory::cas( uint64_t addr, uint32_t rd, uint32_t rs2 )/*{{{*/ | |
409 | { | |
410 | if (msync_object) | |
411 | { | |
412 | mem_xact.referenceType(MemoryTransaction::DATA); | |
413 | mem_xact.paddr(addr); | |
414 | mem_xact.size(4); | |
415 | mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC); | |
416 | ||
417 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
418 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
419 | ||
420 | uint32_t data = mem_xact.getData(); | |
421 | if (data == rs2) | |
422 | { | |
423 | mem_xact.setData(rd); | |
424 | ||
425 | mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC); | |
426 | ||
427 | try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {} | |
428 | try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {} | |
429 | } | |
430 | return data; | |
431 | } | |
432 | else | |
433 | return SS_FastMemory::cas( addr,rd ,rs2); | |
434 | } | |
435 | /*}}}*/ | |
436 | ||
437 | #endif /* MEMORY_MSYNC */ | |
438 |