Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: libc.s | |
5 | * Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
6 | * 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
7 | * | |
8 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; version 2 of the License. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | * | |
23 | * For the avoidance of doubt, and except that if any non-GPL license | |
24 | * choice is available it will apply instead, Sun elects to use only | |
25 | * the General Public License version 2 (GPLv2) at this time for any | |
26 | * software where a choice of GPL license versions is made | |
27 | * available with the language indicating that GPLv2 or any later version | |
28 | * may be used, or where a choice of which version of the GPL is applied is | |
29 | * otherwise unspecified. | |
30 | * | |
31 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
32 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
33 | * have any questions. | |
34 | * | |
35 | * | |
36 | * ========== Copyright Header End ============================================ | |
37 | */ | |
38 | #include "defines.h" | |
39 | ||
40 | !-------------------------------------------------------------------------- | |
41 | ! tso diags related definitions | |
42 | !-------------------------------------------------------------------------- | |
43 | #define LOCK_TIMEOUT 0x100 | |
44 | #define ENTRY(a) .align 32; .global a; a: | |
45 | ||
46 | ||
47 | !-------------------------------------------------------------------------- | |
48 | ||
49 | .section .text | |
50 | ||
51 | .align 4 | |
52 | .global pass | |
53 | pass: | |
54 | ta T_GOOD_TRAP | |
55 | nop | |
56 | ||
57 | .align 4 | |
58 | .global fail | |
59 | fail: | |
60 | ta T_BAD_TRAP | |
61 | nop | |
62 | ||
63 | .align 4 | |
64 | .global memalign | |
65 | memalign: | |
66 | save %sp, -192, %sp | |
67 | ||
68 | mov 1, %o1 | |
69 | mov %i0, %o3 | |
70 | mov %i1, %o2 | |
71 | ta T_SYSCALL | |
72 | nop | |
73 | mov %o4, %o0 | |
74 | ||
75 | ret | |
76 | restore %g0, %o0, %o0 | |
77 | ||
78 | #ifndef MY_PRINTF_ROUTINE | |
79 | .align 4 | |
80 | .global printf | |
81 | printf: | |
82 | ldx [%o0], %g0 | |
83 | simics_printf: | |
84 | nop | |
85 | retl | |
86 | nop | |
87 | #endif | |
88 | ||
89 | #ifndef MY_EXIT_ROUTINE | |
90 | .align 4 | |
91 | .global exit | |
92 | exit: | |
93 | cmp %o0, 0 | |
94 | bne exitfail | |
95 | nop | |
96 | call pass, 0 | |
97 | nop | |
98 | exitfail: | |
99 | call fail, 0 | |
100 | nop | |
101 | #endif | |
102 | ||
103 | #ifndef MY_MPLOCK | |
104 | !-------------------------------------------------------------------------- | |
105 | ! tso diags related library functions | |
106 | !-------------------------------------------------------------------------- | |
107 | !-------------------------------------------------------------------------- | |
108 | ! Ported frm MPCONS test: | |
109 | ! Acquire a lock using ldstub - spins using ldub until lock is free | |
110 | ! status = mplock(addr, owner, timeout, timecount) | |
111 | ! Note: timecount is not used any more. | |
112 | ! Note: simplfied for pre-silicon env purposes. | |
113 | !-------------------------------------------------------------------------- | |
114 | ENTRY(mplock) | |
115 | save %sp, -0xc0, %sp | |
116 | 1: | |
117 | ldstub [%i0], %l1 ! try to acquire lock | |
118 | tst %l1 ! did we get it? | |
119 | bne 2f ! no, branch | |
120 | nop | |
121 | stb %i1, [%i0+1] ! got lock, set owner field | |
122 | ret ! return success | |
123 | restore %g0, 0, %o0 | |
124 | 2: ! didn't get lock | |
125 | mov %i2, %l2 ! set timeout limit | |
126 | 3: | |
127 | ldub [%i0], %l1 ! read lock value | |
128 | tst %l1 ! is it free? | |
129 | beq 1b ! yes, branch | |
130 | ||
131 | subcc %l2, 1, %l2 ! timecount expired? | |
132 | bne 3b ! no, branch | |
133 | nop | |
134 | ||
135 | ret ! timeout occurred | |
136 | restore %g0, 1, %o0 ! return failure | |
137 | #endif | |
138 | !-------------------------------------------------------------------------- | |
139 | ! Ported frm MPCONS test: | |
140 | ! Acquire a lock using ldstub - spins using ldub until lock is free | |
141 | ! status = mplockcasx(addr, owner, timeout, timecount) | |
142 | ! Note: timecount is not used any more. | |
143 | ! Note: simplfied for pre-silicon env purposes. | |
144 | !-------------------------------------------------------------------------- | |
145 | ENTRY(mplockcasx) | |
146 | save %sp, -0xc0, %sp | |
147 | 4: | |
148 | add %i1, 0x100, %l1 | |
149 | casx [%i0], %g0, %l1 ! try to get lock | |
150 | ||
151 | tst %l1 ! did we get it? | |
152 | bne 5f ! no, branch | |
153 | nop | |
154 | stx %i1, [%i0+8] ! got lock, set owner field | |
155 | ret ! return success | |
156 | restore %g0, 0, %o0 | |
157 | 5: ! didn't get lock | |
158 | mov %i2, %l2 ! set timeout limit | |
159 | 6: | |
160 | ldx [%i0], %l1 ! read lock value | |
161 | tst %l1 ! is it free? | |
162 | beq 4b ! yes, branch | |
163 | ||
164 | subcc %l2, 1, %l2 ! timecount expired? | |
165 | bne 6b ! no, branch | |
166 | nop | |
167 | ||
168 | ret ! timeout occurred | |
169 | restore %g0, 1, %o0 ! return failure | |
170 | ||
171 | ||
172 | !-------------------------------------------------------------------------- | |
173 | ! Load a dowbleword | |
174 | ! data1 = loadd(&data2, addr) | |
175 | !-------------------------------------------------------------------------- | |
176 | ENTRY(loadd) | |
177 | mov %o0, %o2 | |
178 | ldd [%o1], %o0 | |
179 | retl | |
180 | st %o1, [%o2] | |
181 | ||
182 | !-------------------------------------------------------------------------- | |
183 | ! Load an extended word | |
184 | ! data = loadx(addr) | |
185 | !-------------------------------------------------------------------------- | |
186 | ENTRY(loadx) | |
187 | retl | |
188 | ldx [%o0], %o0 | |
189 | ||
190 | !-------------------------------------------------------------------------- | |
191 | ! Load a halfword (short), one byte a time | |
192 | ! data = loadh_by_bytes(addr) | |
193 | !-------------------------------------------------------------------------- | |
194 | ENTRY(loadh_by_bytes) | |
195 | ldub [%o0], %o1 | |
196 | sll %o1, 8, %o1 | |
197 | ldub [%o0+1], %o0 | |
198 | retl | |
199 | or %o1, %o0, %o0 | |
200 | ||
201 | !-------------------------------------------------------------------------- | |
202 | ! Load a word, 1 byte at a time | |
203 | ! data = loadw_by_bytes(addr) | |
204 | !-------------------------------------------------------------------------- | |
205 | ENTRY(loadw_by_bytes) | |
206 | ldub [%o0+3], %o4 | |
207 | ldub [%o0+2], %o3 | |
208 | sll %o3, 8, %o3 | |
209 | or %o3, %o4, %o4 | |
210 | ldub [%o0+1], %o2 | |
211 | sll %o2, 16, %o2 | |
212 | or %o2, %o4, %o4 | |
213 | ldub [%o0], %o1 | |
214 | sll %o1, 24, %o1 | |
215 | retl | |
216 | or %o1, %o4, %o0 | |
217 | ||
218 | !-------------------------------------------------------------------------- | |
219 | ! Load a dowbleword, 1 byte at a time | |
220 | ! data1 = loadd_by_bytes(&data2, addr) | |
221 | !-------------------------------------------------------------------------- | |
222 | ENTRY(loadd_by_bytes) | |
223 | save %sp, -0xc0, %sp | |
224 | ldub [%i1+3], %o0 | |
225 | ldub [%i1+2], %o3 | |
226 | sll %o3, 8, %o3 | |
227 | or %o3, %o0, %o0 | |
228 | ldub [%i1+1], %o2 | |
229 | sll %o2, 16, %o2 | |
230 | or %o2, %o0, %o0 | |
231 | ldub [%i1], %o1 | |
232 | sll %o1, 24, %o1 | |
233 | or %o1, %o0, %o0 | |
234 | ldub [%i1+7], %l3 | |
235 | ldub [%i1+6], %l2 | |
236 | sll %l2, 8, %l2 | |
237 | or %l2, %l3, %l3 | |
238 | ldub [%i1+5], %l1 | |
239 | sll %l1, 16, %l1 | |
240 | or %l1, %l3, %l3 | |
241 | ldub [%i1+4], %l0 | |
242 | sll %l0, 24, %l0 | |
243 | or %l0, %l3, %l3 | |
244 | st %l3, [%i0] | |
245 | ret | |
246 | restore %o0, %g0, %o0 | |
247 | ||
248 | ||
249 | ||
250 | !-------------------------------------------------------------------------- | |
251 | ! Load a pointer, 1 byte at a time | |
252 | ! addr = loadp_by_bytes(addr) | |
253 | !-------------------------------------------------------------------------- | |
254 | ENTRY(loadp_by_bytes) | |
255 | save %sp, -0xc0, %sp | |
256 | ldub [%i0+7], %o0 | |
257 | ldub [%i0+6], %l3 | |
258 | sllx %l3, 8, %l3 | |
259 | or %l3, %o0, %o0 | |
260 | ldub [%i0+5], %l2 | |
261 | sllx %l2, 16, %l2 | |
262 | or %l2, %o0, %o0 | |
263 | ldub [%i0+4], %l1 | |
264 | sllx %l1, 24, %l1 | |
265 | or %l1, %o0, %o0 | |
266 | ldub [%i0+3], %l0 | |
267 | sllx %l0, 32, %l0 | |
268 | or %l0, %o0, %o0 | |
269 | ldub [%i0+2], %o3 | |
270 | sllx %o3, 40, %o3 | |
271 | or %o3, %o0, %o0 | |
272 | ldub [%i0+1], %o2 | |
273 | sllx %o2, 48, %o2 | |
274 | or %o2, %o0, %o0 | |
275 | ldub [%i0], %o1 | |
276 | sllx %o1, 56, %o1 | |
277 | or %o1, %o0, %o0 | |
278 | ret | |
279 | restore %o0, %g0, %o0 | |
280 | ||
281 | !-------------------------------------------------------------------------- | |
282 | ! Store a block (64-bytes) | |
283 | ! storeblock(addr) | |
284 | !-------------------------------------------------------------------------- | |
285 | ENTRY(storeblock) | |
286 | retl | |
287 | stda %f0, [%o0] 0xf0 | |
288 | ||
289 | !-------------------------------------------------------------------------- | |
290 | ! load a block | |
291 | ! loadblock(addr) | |
292 | !-------------------------------------------------------------------------- | |
293 | ENTRY(loadblock) | |
294 | retl | |
295 | ldda [%o0] 0xf0, %f0 | |
296 | ||
297 | !-------------------------------------------------------------------------- | |
298 | ! loadb_func(addr) | |
299 | !-------------------------------------------------------------------------- | |
300 | ENTRY(loadb_func) | |
301 | retl | |
302 | ldub [%o0], %o0 | |
303 | ||
304 | !-------------------------------------------------------------------------- | |
305 | ! These below were inline( functions in tests... | |
306 | ! I made the assembly routines. | |
307 | !-------------------------------------------------------------------------- | |
308 | ||
309 | !-------------------------------------------------------------------------- | |
310 | ! Init a lock | |
311 | ! initmplock(addr) | |
312 | !-------------------------------------------------------------------------- | |
313 | ENTRY(initmplock) | |
314 | retl | |
315 | sth %g0, [%o0] | |
316 | ||
317 | !-------------------------------------------------------------------------- | |
318 | ! unlock | |
319 | ! mpunlock(addr) | |
320 | !-------------------------------------------------------------------------- | |
321 | ENTRY(mpunlock) | |
322 | retl | |
323 | sth %g0, [%o0] | |
324 | ||
325 | !-------------------------------------------------------------------------- | |
326 | ! unlock | |
327 | ! mpunlockx(addr) | |
328 | !-------------------------------------------------------------------------- | |
329 | ENTRY(mpunlockx) | |
330 | retl | |
331 | stx %g0, [%o0] | |
332 | ||
333 | !-------------------------------------------------------------------------- | |
334 | ! Load a word | |
335 | ! data = loadw(addr) | |
336 | !-------------------------------------------------------------------------- | |
337 | ENTRY(loadw) | |
338 | retl | |
339 | ld [%o0], %o0 | |
340 | ||
341 | !-------------------------------------------------------------------------- | |
342 | ! Load a halv word | |
343 | ! data = loadh(addr) | |
344 | !-------------------------------------------------------------------------- | |
345 | ENTRY(loadh) | |
346 | retl | |
347 | lduh [%o0], %o0 | |
348 | ||
349 | !-------------------------------------------------------------------------- | |
350 | ! Store a byte | |
351 | ! storeb(data, addr) | |
352 | !-------------------------------------------------------------------------- | |
353 | ENTRY(storeb) | |
354 | retl | |
355 | stb %o0, [%o1] | |
356 | ||
357 | !-------------------------------------------------------------------------- | |
358 | ! Store a word (integer) | |
359 | ! storew(data, addr) | |
360 | !-------------------------------------------------------------------------- | |
361 | ENTRY(storew) | |
362 | retl | |
363 | st %o0, [%o1] | |
364 | ||
365 | !-------------------------------------------------------------------------- | |
366 | ! Store a word (integer) | |
367 | ! storex(data, addr) | |
368 | !-------------------------------------------------------------------------- | |
369 | ENTRY(storex) | |
370 | retl | |
371 | stx %o0, [%o1] | |
372 | ||
373 | !-------------------------------------------------------------------------- | |
374 | ! Store a doubleword | |
375 | ! stored(data1, data2, addr) | |
376 | !-------------------------------------------------------------------------- | |
377 | ENTRY(stored) | |
378 | retl | |
379 | std %o0, [%o2] | |
380 | ||
381 | !-------------------------------------------------------------------------- | |
382 | ! Swap a word | |
383 | ! data = swap(data, addr) | |
384 | !-------------------------------------------------------------------------- | |
385 | ENTRY(swap) | |
386 | retl | |
387 | swap [%o1], %o0 | |
388 | ||
389 | !-------------------------------------------------------------------------- | |
390 | ! Compare and swap a word | |
391 | ! data = casa(data, addr) | |
392 | !-------------------------------------------------------------------------- | |
393 | ENTRY(casa) | |
394 | retl | |
395 | casa [%o1] 0x80, %g0, %o0 | |
396 | ||
397 | !-------------------------------------------------------------------------- | |
398 | ! Store a halfword (short), 1 byte at a time | |
399 | ! storeh_by_bytes(data, addr) | |
400 | !-------------------------------------------------------------------------- | |
401 | ENTRY(storeh_by_bytes) | |
402 | stb %o0, [%o1+1] | |
403 | srl %o0, 8, %o2 | |
404 | retl | |
405 | stb %o2, [%o1] | |
406 | ||
407 | !-------------------------------------------------------------------------- | |
408 | ! Store a word (integer), 1 byte at a time | |
409 | ! storew_by_bytes(data, addr) | |
410 | !-------------------------------------------------------------------------- | |
411 | ENTRY(storew_by_bytes) | |
412 | stb %o0, [%o1+3] | |
413 | srl %o0, 24, %o2 | |
414 | stb %o2, [%o1] | |
415 | srl %o0, 16, %o3 | |
416 | stb %o3, [%o1+1] | |
417 | srl %o0, 8, %o4 | |
418 | retl | |
419 | stb %o4, [%o1+2] | |
420 | ||
421 | !-------------------------------------------------------------------------- | |
422 | ! Prefetch a line for many reads - loads into E$ | |
423 | ! prefetch_for_read_many(addr) | |
424 | !-------------------------------------------------------------------------- | |
425 | ENTRY(prefetch_for_read_many) | |
426 | retl | |
427 | prefetch [%o0], 0 | |
428 | ||
429 | !-------------------------------------------------------------------------- | |
430 | ! Prefetch a line for one reads - loads into P$ | |
431 | ! prefetch_for_read_once(addr) | |
432 | !-------------------------------------------------------------------------- | |
433 | ENTRY(prefetch_for_read_once) | |
434 | retl | |
435 | prefetch [%o0], 1 | |
436 | ||
437 | !-------------------------------------------------------------------------- | |
438 | ! Prefetch a line for write | |
439 | ! prefetch_for_write_many(addr) | |
440 | !-------------------------------------------------------------------------- | |
441 | ENTRY(prefetch_for_write_many) | |
442 | retl | |
443 | prefetch [%o0], 2 | |
444 | ||
445 | !-------------------------------------------------------------------------- | |
446 | ! Prefetch a line for write | |
447 | ! prefetch_for_write_once(addr) | |
448 | !-------------------------------------------------------------------------- | |
449 | ENTRY(prefetch_for_write_once) | |
450 | retl | |
451 | prefetch [%o0], 3 | |
452 | ||
453 | ||
454 | !-------------------------------------------------------------------------- | |
455 | ! membar_sync() | |
456 | !-------------------------------------------------------------------------- | |
457 | ENTRY(membar_sync) | |
458 | retl | |
459 | membar 0x40 | |
460 | ||
461 | !-------------------------------------------------------------------------- | |
462 | ! membar_store_load() | |
463 | !-------------------------------------------------------------------------- | |
464 | ENTRY(membar_storeload) | |
465 | retl | |
466 | membar #StoreLoad | |
467 | ||
468 | !-------------------------------------------------------------------------- | |
469 | ! ldstub(addr) | |
470 | !-------------------------------------------------------------------------- | |
471 | ENTRY(ldstub) | |
472 | retl | |
473 | ldstub [%o0], %o0 | |
474 | ||
475 | !-------------------------------------------------------------------------- | |
476 | ! Load a pointer | |
477 | ! addr1 = loadp(addr) | |
478 | !-------------------------------------------------------------------------- | |
479 | ENTRY(loadp) | |
480 | retl | |
481 | ldx [%o0], %o0 | |
482 | ||
483 | !-------------------------------------------------------------------------- | |
484 | ! Store a pointer | |
485 | ! storep(addr1, addr) | |
486 | !-------------------------------------------------------------------------- | |
487 | ENTRY(storep) | |
488 | retl | |
489 | stx %o0, [%o1] | |
490 | ||
491 | !================= end for now ============================================ |