6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * General machine architecture & implementation specific
30 * assembly language routines.
31 */
32 #if defined(lint)
33 #include <sys/types.h>
34 #include <sys/machsystm.h>
35 #include <sys/t_lock.h>
36 #else /* lint */
37 #include "assym.h"
38 #endif /* lint */
39
40 #include <sys/asm_linkage.h>
41 #include <sys/async.h>
42 #include <sys/machthread.h>
43 #include <sys/vis.h>
44 #include <sys/machsig.h>
45
46 #if defined(lint)
47 caddr_t
48 set_trap_table(void)
49 {
50 return ((caddr_t)0);
51 }
52 #else /* lint */
53
54 ENTRY(set_trap_table)
55 set trap_table, %o1
56 rdpr %tba, %o0
57 wrpr %o1, %tba
58 retl
59 wrpr %g0, WSTATE_KERN, %wstate
60 SET_SIZE(set_trap_table)
61
62 #endif /* lint */
63
64 #if defined(lint)
65
66 /*ARGSUSED*/
67 void
68 stphys(uint64_t physaddr, int value)
69 {}
70
71 /*ARGSUSED*/
72 int
73 ldphys(uint64_t physaddr)
74 { return (0); }
75
76 /*ARGSUSED*/
77 void
78 stdphys(uint64_t physaddr, uint64_t value)
79 {}
80
81 /*ARGSUSED*/
82 uint64_t
83 lddphys(uint64_t physaddr)
84 { return (0x0ull); }
85
86 /* ARGSUSED */
87 void
88 stphysio(u_longlong_t physaddr, uint_t value)
89 {}
90
91 /* ARGSUSED */
92 uint_t
93 ldphysio(u_longlong_t physaddr)
94 { return(0); }
95
96 /* ARGSUSED */
97 void
98 sthphysio(u_longlong_t physaddr, ushort_t value)
99 {}
100
101 /* ARGSUSED */
102 ushort_t
103 ldhphysio(u_longlong_t physaddr)
104 { return(0); }
105
106 /* ARGSUSED */
107 void
108 stbphysio(u_longlong_t physaddr, uchar_t value)
109 {}
110
111 /* ARGSUSED */
112 uchar_t
113 ldbphysio(u_longlong_t physaddr)
114 { return(0); }
115
116 /*ARGSUSED*/
117 void
118 stdphysio(u_longlong_t physaddr, u_longlong_t value)
119 {}
120
121 /*ARGSUSED*/
122 u_longlong_t
123 lddphysio(u_longlong_t physaddr)
124 { return (0ull); }
125
126 #else
127
128 ! Store long word value at physical address
129 !
130 ! void stdphys(uint64_t physaddr, uint64_t value)
131 !
132 ENTRY(stdphys)
133 /*
134 * disable interrupts, clear Address Mask to access 64 bit physaddr
135 */
136 rdpr %pstate, %o4
137 andn %o4, PSTATE_IE | PSTATE_AM, %o5
138 wrpr %o5, 0, %pstate
139 stxa %o1, [%o0]ASI_MEM
140 retl
141 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
142 SET_SIZE(stdphys)
143
144
145 ! Store long word value at physical i/o address
146 !
147 ! void stdphysio(u_longlong_t physaddr, u_longlong_t value)
283 andn %o4, PSTATE_IE | PSTATE_AM, %o5
284 wrpr %o5, 0, %pstate
285 lduha [%o0]ASI_IO, %o0 /* load value via bypass ASI */
286 retl
287 wrpr %g0, %o4, %pstate /* restore pstate */
288 SET_SIZE(ldhphysio)
289
290 !
291 ! load byte value at physical address in I/O space
292 !
293 ! uchar_t ldbphysio(u_longlong_t physaddr)
294 !
295 ENTRY_NP(ldbphysio)
296 rdpr %pstate, %o4 /* read PSTATE reg */
297 andn %o4, PSTATE_IE | PSTATE_AM, %o5
298 wrpr %o5, 0, %pstate
299 lduba [%o0]ASI_IO, %o0 /* load value via bypass ASI */
300 retl
301 wrpr %g0, %o4, %pstate /* restore pstate */
302 SET_SIZE(ldbphysio)
303 #endif /* lint */
304
305 /*
306 * save_gsr(kfpu_t *fp)
307 * Store the graphics status register
308 */
309
310 #if defined(lint) || defined(__lint)
311
312 /* ARGSUSED */
313 void
314 save_gsr(kfpu_t *fp)
315 {}
316
317 #else /* lint */
318
319 ENTRY_NP(save_gsr)
320 rd %gsr, %g2 ! save gsr
321 retl
322 stx %g2, [%o0 + FPU_GSR]
323 SET_SIZE(save_gsr)
324
325 #endif /* lint */
326
327 #if defined(lint) || defined(__lint)
328
329 /* ARGSUSED */
330 void
331 restore_gsr(kfpu_t *fp)
332 {}
333
334 #else /* lint */
335
336 ENTRY_NP(restore_gsr)
337 ldx [%o0 + FPU_GSR], %g2
338 wr %g2, %g0, %gsr
339 retl
340 nop
341 SET_SIZE(restore_gsr)
342
343 #endif /* lint */
344
345 /*
346 * uint64_t
347 * _fp_read_pgsr()
348 * Get the graphics status register info from fp and return it
349 */
350
351 #if defined(lint) || defined(__lint)
352
353 /* ARGSUSED */
354 uint64_t
355 _fp_read_pgsr(kfpu_t *fp)
356 { return 0; }
357
358 #else /* lint */
359
360 ENTRY_NP(_fp_read_pgsr)
361 retl
362 rd %gsr, %o0
363 SET_SIZE(_fp_read_pgsr)
364
365 #endif /* lint */
366
367
368 /*
369 * uint64_t
370 * get_gsr(kfpu_t *fp)
371 * Get the graphics status register info from fp and return it
372 */
373
374 #if defined(lint) || defined(__lint)
375
376 /* ARGSUSED */
377 uint64_t
378 get_gsr(kfpu_t *fp)
379 { return 0; }
380
381 #else /* lint */
382
383 ENTRY_NP(get_gsr)
384 retl
385 ldx [%o0 + FPU_GSR], %o0
386 SET_SIZE(get_gsr)
387
388 #endif
389
390 /*
391 * _fp_write_pgsr(uint64_t *buf, kfpu_t *fp)
392 * Set the graphics status register info to fp from buf
393 */
394
395 #if defined(lint) || defined(__lint)
396
397 /* ARGSUSED */
398 void
399 _fp_write_pgsr(uint64_t buf, kfpu_t *fp)
400 {}
401
402 #else /* lint */
403
404 ENTRY_NP(_fp_write_pgsr)
405 retl
406 mov %o0, %gsr
407 SET_SIZE(_fp_write_pgsr)
408
409 #endif /* lint */
410
411 /*
412 * set_gsr(uint64_t buf, kfpu_t *fp)
413 * Set the graphics status register info to fp from buf
414 */
415
416 #if defined(lint) || defined(__lint)
417
418 /* ARGSUSED */
419 void
420 set_gsr(uint64_t buf, kfpu_t *fp)
421 {}
422
423 #else /* lint */
424
425 ENTRY_NP(set_gsr)
426 retl
427 stx %o0, [%o1 + FPU_GSR]
428 SET_SIZE(set_gsr)
429
430 #endif /* lint */
431
432 #if defined(lint) || defined(__lint)
433 void
434 kdi_cpu_index(void)
435 {
436 }
437
438 #else /* lint */
439
440 ENTRY_NP(kdi_cpu_index)
441 CPU_INDEX(%g1, %g2)
442 jmp %g7
443 nop
444 SET_SIZE(kdi_cpu_index)
445
446 #endif /* lint */
447
448 #if defined(lint) || defined(__lint)
449 void
450 kmdb_enter(void)
451 {
452 }
453
454 #else /* lint */
455
456 ENTRY_NP(kmdb_enter)
457 t ST_KMDB_TRAP
458 retl
459 nop
460 SET_SIZE(kmdb_enter)
461
462 #endif /* lint */
463
464 /*
465 * The Spitfire floating point code has been changed not to use install/
466 * save/restore/fork/freectx() because of the special memcpy library
467 * routines, which will lose too much performance if they have to go
468 * through the fp_disabled trap (which used to call installctx()). So
469 * now fp_save/fp_restore are called from resume, and they don't care
470 * whether floating point was enabled from the user program via the
471 * fp_enabled trap or from the memcpy library, which just turns on floating
472 * point in the fprs register itself. The new routine lwp_freeregs is
473 * called everywhere freectx is called, and code was added to the sun4u-
474 * specific version of lwp_forkregs (which is called everywhere forkctx
475 * is called) to handle forking the floating point registers.
476 *
477 * Note that for the fprs dirty upper/lower bits are not used for now,
478 * because the #instructions to determine if we need to use them is probably
479 * greater than the #insructions just using them. This is a possible future
480 * optimization, only do it with very careful benchmarking!
481 *
482 * The fp_fksave and and fp_load were split into two routines for the
483 * sake of efficiency between the getfpregs/xregs_getfpregs and
484 * setfpregs/xregs_setfpregs. But note that for saving and restoring
485 * context, both *must* happen. For prmachdep, aka access from [k]adb,
486 * it's OK if only one part happens.
487 */
488
489 /*
490 * fp_save(kfpu_t *fp)
491 * fp_fksave(kfpu_t *fp)
492 * Store the floating point registers.
493 */
494
495 #if defined(lint) || defined(__lint)
496
497 /* ARGSUSED */
498 void
499 fp_save(kfpu_t *fp)
500 {}
501
502 /* ARGSUSED */
503 void
504 fp_fksave(kfpu_t *fp)
505 {}
506
507 #else /* lint */
508
509 ENTRY_NP(fp_save)
510 ALTENTRY(fp_fksave)
511 BSTORE_FPREGS(%o0, %o1) ! store V9 regs
512 retl
513 stx %fsr, [%o0 + FPU_FSR] ! store fsr
514 SET_SIZE(fp_fksave)
515 SET_SIZE(fp_save)
516
517 #endif /* lint */
518
519 /*
520 * fp_v8_fksave(kfpu_t *fp)
521 *
522 * This is like the above routine but only saves the lower half.
523 */
524
525 #if defined(lint) || defined(__lint)
526
527 /* ARGSUSED */
528 void
529 fp_v8_fksave(kfpu_t *fp)
530 {}
531
532 #else /* lint */
533
534 ENTRY_NP(fp_v8_fksave)
535 BSTORE_V8_FPREGS(%o0, %o1) ! store V8 regs
536 retl
537 stx %fsr, [%o0 + FPU_FSR] ! store fsr
538 SET_SIZE(fp_v8_fksave)
539
540 #endif /* lint */
541
542 /*
543 * fp_v8p_fksave(kfpu_t *fp)
544 *
545 * This is like the above routine but only saves the upper half.
546 */
547
548 #if defined(lint) || defined(__lint)
549
550 /* ARGSUSED */
551 void
552 fp_v8p_fksave(kfpu_t *fp)
553 {}
554
555 #else /* lint */
556
557 ENTRY_NP(fp_v8p_fksave)
558 BSTORE_V8P_FPREGS(%o0, %o1) ! store V9 extra regs
559 retl
560 stx %fsr, [%o0 + FPU_FSR] ! store fsr
561 SET_SIZE(fp_v8p_fksave)
562
563 #endif /* lint */
564
565 /*
566 * fp_restore(kfpu_t *fp)
567 */
568
569 #if defined(lint) || defined(__lint)
570
571 /* ARGSUSED */
572 void
573 fp_restore(kfpu_t *fp)
574 {}
575
576 #else /* lint */
577
578 ENTRY_NP(fp_restore)
579 BLOAD_FPREGS(%o0, %o1) ! load V9 regs
580 retl
581 ldx [%o0 + FPU_FSR], %fsr ! restore fsr
582 SET_SIZE(fp_restore)
583
584 #endif /* lint */
585
586 /*
587 * fp_v8_load(kfpu_t *fp)
588 */
589
590 #if defined(lint) || defined(__lint)
591
592 /* ARGSUSED */
593 void
594 fp_v8_load(kfpu_t *fp)
595 {}
596
597 #else /* lint */
598
599 ENTRY_NP(fp_v8_load)
600 BLOAD_V8_FPREGS(%o0, %o1) ! load V8 regs
601 retl
602 ldx [%o0 + FPU_FSR], %fsr ! restore fsr
603 SET_SIZE(fp_v8_load)
604
605 #endif /* lint */
606
607 /*
608 * fp_v8p_load(kfpu_t *fp)
609 */
610
611 #if defined(lint) || defined(__lint)
612
613 /* ARGSUSED */
614 void
615 fp_v8p_load(kfpu_t *fp)
616 {}
617
618 #else /* lint */
619
620 ENTRY_NP(fp_v8p_load)
621 BLOAD_V8P_FPREGS(%o0, %o1) ! load V9 extra regs
622 retl
623 ldx [%o0 + FPU_FSR], %fsr ! restore fsr
624 SET_SIZE(fp_v8p_load)
625
626 #endif /* lint */
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * General machine architecture & implementation specific
28 * assembly language routines.
29 */
30 #include "assym.h"
31
32 #include <sys/asm_linkage.h>
33 #include <sys/async.h>
34 #include <sys/machthread.h>
35 #include <sys/vis.h>
36 #include <sys/machsig.h>
37
38 ENTRY(set_trap_table)
39 set trap_table, %o1
40 rdpr %tba, %o0
41 wrpr %o1, %tba
42 retl
43 wrpr %g0, WSTATE_KERN, %wstate
44 SET_SIZE(set_trap_table)
45
46 ! Store long word value at physical address
47 !
48 ! void stdphys(uint64_t physaddr, uint64_t value)
49 !
50 ENTRY(stdphys)
51 /*
52 * disable interrupts, clear Address Mask to access 64 bit physaddr
53 */
54 rdpr %pstate, %o4
55 andn %o4, PSTATE_IE | PSTATE_AM, %o5
56 wrpr %o5, 0, %pstate
57 stxa %o1, [%o0]ASI_MEM
58 retl
59 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
60 SET_SIZE(stdphys)
61
62
63 ! Store long word value at physical i/o address
64 !
65 ! void stdphysio(u_longlong_t physaddr, u_longlong_t value)
201 andn %o4, PSTATE_IE | PSTATE_AM, %o5
202 wrpr %o5, 0, %pstate
203 lduha [%o0]ASI_IO, %o0 /* load value via bypass ASI */
204 retl
205 wrpr %g0, %o4, %pstate /* restore pstate */
206 SET_SIZE(ldhphysio)
207
208 !
209 ! load byte value at physical address in I/O space
210 !
211 ! uchar_t ldbphysio(u_longlong_t physaddr)
212 !
213 ENTRY_NP(ldbphysio)
214 rdpr %pstate, %o4 /* read PSTATE reg */
215 andn %o4, PSTATE_IE | PSTATE_AM, %o5
216 wrpr %o5, 0, %pstate
217 lduba [%o0]ASI_IO, %o0 /* load value via bypass ASI */
218 retl
219 wrpr %g0, %o4, %pstate /* restore pstate */
220 SET_SIZE(ldbphysio)
221
222 /*
223 * save_gsr(kfpu_t *fp)
224 * Store the graphics status register
225 */
226
227 ENTRY_NP(save_gsr)
228 rd %gsr, %g2 ! save gsr
229 retl
230 stx %g2, [%o0 + FPU_GSR]
231 SET_SIZE(save_gsr)
232
233 ENTRY_NP(restore_gsr)
234 ldx [%o0 + FPU_GSR], %g2
235 wr %g2, %g0, %gsr
236 retl
237 nop
238 SET_SIZE(restore_gsr)
239
240 /*
241 * uint64_t
242 * _fp_read_pgsr()
243 * Get the graphics status register info from fp and return it
244 */
245
246 ENTRY_NP(_fp_read_pgsr)
247 retl
248 rd %gsr, %o0
249 SET_SIZE(_fp_read_pgsr)
250
251
252 /*
253 * uint64_t
254 * get_gsr(kfpu_t *fp)
255 * Get the graphics status register info from fp and return it
256 */
257
258 ENTRY_NP(get_gsr)
259 retl
260 ldx [%o0 + FPU_GSR], %o0
261 SET_SIZE(get_gsr)
262
263 /*
264 * _fp_write_pgsr(uint64_t *buf, kfpu_t *fp)
265 * Set the graphics status register info to fp from buf
266 */
267
268 ENTRY_NP(_fp_write_pgsr)
269 retl
270 mov %o0, %gsr
271 SET_SIZE(_fp_write_pgsr)
272
273 /*
274 * set_gsr(uint64_t buf, kfpu_t *fp)
275 * Set the graphics status register info to fp from buf
276 */
277
278 ENTRY_NP(set_gsr)
279 retl
280 stx %o0, [%o1 + FPU_GSR]
281 SET_SIZE(set_gsr)
282
283 ENTRY_NP(kdi_cpu_index)
284 CPU_INDEX(%g1, %g2)
285 jmp %g7
286 nop
287 SET_SIZE(kdi_cpu_index)
288
289 ENTRY_NP(kmdb_enter)
290 t ST_KMDB_TRAP
291 retl
292 nop
293 SET_SIZE(kmdb_enter)
294
295 /*
296 * The Spitfire floating point code has been changed not to use install/
297 * save/restore/fork/freectx() because of the special memcpy library
298 * routines, which will lose too much performance if they have to go
299 * through the fp_disabled trap (which used to call installctx()). So
300 * now fp_save/fp_restore are called from resume, and they don't care
301 * whether floating point was enabled from the user program via the
302 * fp_enabled trap or from the memcpy library, which just turns on floating
303 * point in the fprs register itself. The new routine lwp_freeregs is
304 * called everywhere freectx is called, and code was added to the sun4u-
305 * specific version of lwp_forkregs (which is called everywhere forkctx
306 * is called) to handle forking the floating point registers.
307 *
308 * Note that for the fprs dirty upper/lower bits are not used for now,
309 * because the #instructions to determine if we need to use them is probably
310 * greater than the #insructions just using them. This is a possible future
311 * optimization, only do it with very careful benchmarking!
312 *
313 * The fp_fksave and and fp_load were split into two routines for the
314 * sake of efficiency between the getfpregs/xregs_getfpregs and
315 * setfpregs/xregs_setfpregs. But note that for saving and restoring
316 * context, both *must* happen. For prmachdep, aka access from [k]adb,
317 * it's OK if only one part happens.
318 */
319
320 /*
321 * fp_save(kfpu_t *fp)
322 * fp_fksave(kfpu_t *fp)
323 * Store the floating point registers.
324 */
325
326 ENTRY_NP(fp_save)
327 ALTENTRY(fp_fksave)
328 BSTORE_FPREGS(%o0, %o1) ! store V9 regs
329 retl
330 stx %fsr, [%o0 + FPU_FSR] ! store fsr
331 SET_SIZE(fp_fksave)
332 SET_SIZE(fp_save)
333
334 /*
335 * fp_v8_fksave(kfpu_t *fp)
336 *
337 * This is like the above routine but only saves the lower half.
338 */
339
340 ENTRY_NP(fp_v8_fksave)
341 BSTORE_V8_FPREGS(%o0, %o1) ! store V8 regs
342 retl
343 stx %fsr, [%o0 + FPU_FSR] ! store fsr
344 SET_SIZE(fp_v8_fksave)
345
346 /*
347 * fp_v8p_fksave(kfpu_t *fp)
348 *
349 * This is like the above routine but only saves the upper half.
350 */
351
352 ENTRY_NP(fp_v8p_fksave)
353 BSTORE_V8P_FPREGS(%o0, %o1) ! store V9 extra regs
354 retl
355 stx %fsr, [%o0 + FPU_FSR] ! store fsr
356 SET_SIZE(fp_v8p_fksave)
357
358 /*
359 * fp_restore(kfpu_t *fp)
360 */
361
362 ENTRY_NP(fp_restore)
363 BLOAD_FPREGS(%o0, %o1) ! load V9 regs
364 retl
365 ldx [%o0 + FPU_FSR], %fsr ! restore fsr
366 SET_SIZE(fp_restore)
367
368 /*
369 * fp_v8_load(kfpu_t *fp)
370 */
371
372 ENTRY_NP(fp_v8_load)
373 BLOAD_V8_FPREGS(%o0, %o1) ! load V8 regs
374 retl
375 ldx [%o0 + FPU_FSR], %fsr ! restore fsr
376 SET_SIZE(fp_v8_load)
377
378 /*
379 * fp_v8p_load(kfpu_t *fp)
380 */
381
382 ENTRY_NP(fp_v8p_load)
383 BLOAD_V8P_FPREGS(%o0, %o1) ! load V9 extra regs
384 retl
385 ldx [%o0 + FPU_FSR], %fsr ! restore fsr
386 SET_SIZE(fp_v8p_load)
387
|