6811333 Remove prom_printf() message in emlxs driver
[opensolaris.git] / usr / src / uts / sun4 / ml / subr_asm.s
blobacfa423775ca247b4878a67c0078ad99d9c1eb11
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * General machine architecture & implementation specific
30 * assembly language routines.
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 */
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>
46 #if defined(lint)
47 caddr_t
48 set_trap_table(void)
50 return ((caddr_t)0);
52 #else /* lint */
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)
62 #endif /* lint */
64 #if defined(lint)
66 /*ARGSUSED*/
67 void
68 stphys(uint64_t physaddr, int value)
71 /*ARGSUSED*/
72 int
73 ldphys(uint64_t physaddr)
74 { return (0); }
76 /*ARGSUSED*/
77 void
78 stdphys(uint64_t physaddr, uint64_t value)
81 /*ARGSUSED*/
82 uint64_t
83 lddphys(uint64_t physaddr)
84 { return (0x0ull); }
86 /* ARGSUSED */
87 void
88 stphysio(u_longlong_t physaddr, uint_t value)
91 /* ARGSUSED */
92 uint_t
93 ldphysio(u_longlong_t physaddr)
94 { return(0); }
96 /* ARGSUSED */
97 void
98 sthphysio(u_longlong_t physaddr, ushort_t value)
101 /* ARGSUSED */
102 ushort_t
103 ldhphysio(u_longlong_t physaddr)
104 { return(0); }
106 /* ARGSUSED */
107 void
108 stbphysio(u_longlong_t physaddr, uchar_t value)
111 /* ARGSUSED */
112 uchar_t
113 ldbphysio(u_longlong_t physaddr)
114 { return(0); }
116 /*ARGSUSED*/
117 void
118 stdphysio(u_longlong_t physaddr, u_longlong_t value)
121 /*ARGSUSED*/
122 u_longlong_t
123 lddphysio(u_longlong_t physaddr)
124 { return (0ull); }
126 #else
128 ! Store long word value at physical address
130 ! void stdphys(uint64_t physaddr, uint64_t value)
132 ENTRY(stdphys)
134 * disable interrupts, clear Address Mask to access 64 bit physaddr
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)
145 ! Store long word value at physical i/o address
147 ! void stdphysio(u_longlong_t physaddr, u_longlong_t value)
149 ENTRY(stdphysio)
151 * disable interrupts, clear Address Mask to access 64 bit physaddr
153 rdpr %pstate, %o4
154 andn %o4, PSTATE_IE | PSTATE_AM, %o5
155 wrpr %o5, 0, %pstate ! clear IE, AM bits
156 stxa %o1, [%o0]ASI_IO
157 retl
158 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
159 SET_SIZE(stdphysio)
163 ! Load long word value at physical address
165 ! uint64_t lddphys(uint64_t physaddr)
167 ENTRY(lddphys)
168 rdpr %pstate, %o4
169 andn %o4, PSTATE_IE | PSTATE_AM, %o5
170 wrpr %o5, 0, %pstate
171 ldxa [%o0]ASI_MEM, %o0
172 retl
173 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
174 SET_SIZE(lddphys)
177 ! Load long word value at physical i/o address
179 ! unsigned long long lddphysio(u_longlong_t physaddr)
181 ENTRY(lddphysio)
182 rdpr %pstate, %o4
183 andn %o4, PSTATE_IE | PSTATE_AM, %o5
184 wrpr %o5, 0, %pstate ! clear IE, AM bits
185 ldxa [%o0]ASI_IO, %o0
186 retl
187 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
188 SET_SIZE(lddphysio)
191 ! Store value at physical address
193 ! void stphys(uint64_t physaddr, int value)
195 ENTRY(stphys)
196 rdpr %pstate, %o4
197 andn %o4, PSTATE_IE | PSTATE_AM, %o5
198 wrpr %o5, 0, %pstate
199 sta %o1, [%o0]ASI_MEM
200 retl
201 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
202 SET_SIZE(stphys)
206 ! load value at physical address
208 ! int ldphys(uint64_t physaddr)
210 ENTRY(ldphys)
211 rdpr %pstate, %o4
212 andn %o4, PSTATE_IE | PSTATE_AM, %o5
213 wrpr %o5, 0, %pstate
214 lda [%o0]ASI_MEM, %o0
215 srl %o0, 0, %o0 ! clear upper 32 bits
216 retl
217 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
218 SET_SIZE(ldphys)
221 ! Store value into physical address in I/O space
223 ! void stphysio(u_longlong_t physaddr, uint_t value)
225 ENTRY_NP(stphysio)
226 rdpr %pstate, %o4 /* read PSTATE reg */
227 andn %o4, PSTATE_IE | PSTATE_AM, %o5
228 wrpr %o5, 0, %pstate
229 stwa %o1, [%o0]ASI_IO /* store value via bypass ASI */
230 retl
231 wrpr %g0, %o4, %pstate /* restore the PSTATE */
232 SET_SIZE(stphysio)
235 ! Store value into physical address in I/O space
237 ! void sthphysio(u_longlong_t physaddr, ushort_t value)
239 ENTRY_NP(sthphysio)
240 rdpr %pstate, %o4 /* read PSTATE reg */
241 andn %o4, PSTATE_IE | PSTATE_AM, %o5
242 wrpr %o5, 0, %pstate
243 stha %o1, [%o0]ASI_IO /* store value via bypass ASI */
244 retl
245 wrpr %g0, %o4, %pstate /* restore the PSTATE */
246 SET_SIZE(sthphysio)
249 ! Store value into one byte physical address in I/O space
251 ! void stbphysio(u_longlong_t physaddr, uchar_t value)
253 ENTRY_NP(stbphysio)
254 rdpr %pstate, %o4 /* read PSTATE reg */
255 andn %o4, PSTATE_IE | PSTATE_AM, %o5
256 wrpr %o5, 0, %pstate
257 stba %o1, [%o0]ASI_IO /* store byte via bypass ASI */
258 retl
259 wrpr %g0, %o4, %pstate /* restore the PSTATE */
260 SET_SIZE(stbphysio)
263 ! load value at physical address in I/O space
265 ! uint_t ldphysio(u_longlong_t physaddr)
267 ENTRY_NP(ldphysio)
268 rdpr %pstate, %o4 /* read PSTATE reg */
269 andn %o4, PSTATE_IE | PSTATE_AM, %o5
270 wrpr %o5, 0, %pstate
271 lduwa [%o0]ASI_IO, %o0 /* load value via bypass ASI */
272 retl
273 wrpr %g0, %o4, %pstate /* restore pstate */
274 SET_SIZE(ldphysio)
277 ! load value at physical address in I/O space
279 ! ushort_t ldhphysio(u_longlong_t physaddr)
281 ENTRY_NP(ldhphysio)
282 rdpr %pstate, %o4 /* read PSTATE reg */
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)
291 ! load byte value at physical address in I/O space
293 ! uchar_t ldbphysio(u_longlong_t physaddr)
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 */
306 * save_gsr(kfpu_t *fp)
307 * Store the graphics status register
310 #if defined(lint) || defined(__lint)
312 /* ARGSUSED */
313 void
314 save_gsr(kfpu_t *fp)
317 #else /* lint */
319 ENTRY_NP(save_gsr)
320 rd %gsr, %g2 ! save gsr
321 retl
322 stx %g2, [%o0 + FPU_GSR]
323 SET_SIZE(save_gsr)
325 #endif /* lint */
327 #if defined(lint) || defined(__lint)
329 /* ARGSUSED */
330 void
331 restore_gsr(kfpu_t *fp)
334 #else /* lint */
336 ENTRY_NP(restore_gsr)
337 ldx [%o0 + FPU_GSR], %g2
338 wr %g2, %g0, %gsr
339 retl
341 SET_SIZE(restore_gsr)
343 #endif /* lint */
346 * uint64_t
347 * _fp_read_pgsr()
348 * Get the graphics status register info from fp and return it
351 #if defined(lint) || defined(__lint)
353 /* ARGSUSED */
354 uint64_t
355 _fp_read_pgsr(kfpu_t *fp)
356 { return 0; }
358 #else /* lint */
360 ENTRY_NP(_fp_read_pgsr)
361 retl
362 rd %gsr, %o0
363 SET_SIZE(_fp_read_pgsr)
365 #endif /* lint */
369 * uint64_t
370 * get_gsr(kfpu_t *fp)
371 * Get the graphics status register info from fp and return it
374 #if defined(lint) || defined(__lint)
376 /* ARGSUSED */
377 uint64_t
378 get_gsr(kfpu_t *fp)
379 { return 0; }
381 #else /* lint */
383 ENTRY_NP(get_gsr)
384 retl
385 ldx [%o0 + FPU_GSR], %o0
386 SET_SIZE(get_gsr)
388 #endif
391 * _fp_write_pgsr(uint64_t *buf, kfpu_t *fp)
392 * Set the graphics status register info to fp from buf
395 #if defined(lint) || defined(__lint)
397 /* ARGSUSED */
398 void
399 _fp_write_pgsr(uint64_t buf, kfpu_t *fp)
402 #else /* lint */
404 ENTRY_NP(_fp_write_pgsr)
405 retl
406 mov %o0, %gsr
407 SET_SIZE(_fp_write_pgsr)
409 #endif /* lint */
412 * set_gsr(uint64_t buf, kfpu_t *fp)
413 * Set the graphics status register info to fp from buf
416 #if defined(lint) || defined(__lint)
418 /* ARGSUSED */
419 void
420 set_gsr(uint64_t buf, kfpu_t *fp)
423 #else /* lint */
425 ENTRY_NP(set_gsr)
426 retl
427 stx %o0, [%o1 + FPU_GSR]
428 SET_SIZE(set_gsr)
430 #endif /* lint */
432 #if defined(lint) || defined(__lint)
433 void
434 kdi_cpu_index(void)
438 #else /* lint */
440 ENTRY_NP(kdi_cpu_index)
441 CPU_INDEX(%g1, %g2)
442 jmp %g7
444 SET_SIZE(kdi_cpu_index)
446 #endif /* lint */
448 #if defined(lint) || defined(__lint)
449 void
450 kmdb_enter(void)
454 #else /* lint */
456 ENTRY_NP(kmdb_enter)
457 t ST_KMDB_TRAP
458 retl
460 SET_SIZE(kmdb_enter)
462 #endif /* lint */
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.
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!
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.
490 * fp_save(kfpu_t *fp)
491 * fp_fksave(kfpu_t *fp)
492 * Store the floating point registers.
495 #if defined(lint) || defined(__lint)
497 /* ARGSUSED */
498 void
499 fp_save(kfpu_t *fp)
502 /* ARGSUSED */
503 void
504 fp_fksave(kfpu_t *fp)
507 #else /* lint */
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)
517 #endif /* lint */
520 * fp_v8_fksave(kfpu_t *fp)
522 * This is like the above routine but only saves the lower half.
525 #if defined(lint) || defined(__lint)
527 /* ARGSUSED */
528 void
529 fp_v8_fksave(kfpu_t *fp)
532 #else /* lint */
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)
540 #endif /* lint */
543 * fp_v8p_fksave(kfpu_t *fp)
545 * This is like the above routine but only saves the upper half.
548 #if defined(lint) || defined(__lint)
550 /* ARGSUSED */
551 void
552 fp_v8p_fksave(kfpu_t *fp)
555 #else /* lint */
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)
563 #endif /* lint */
566 * fp_restore(kfpu_t *fp)
569 #if defined(lint) || defined(__lint)
571 /* ARGSUSED */
572 void
573 fp_restore(kfpu_t *fp)
576 #else /* lint */
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)
584 #endif /* lint */
587 * fp_v8_load(kfpu_t *fp)
590 #if defined(lint) || defined(__lint)
592 /* ARGSUSED */
593 void
594 fp_v8_load(kfpu_t *fp)
597 #else /* lint */
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)
605 #endif /* lint */
608 * fp_v8p_load(kfpu_t *fp)
611 #if defined(lint) || defined(__lint)
613 /* ARGSUSED */
614 void
615 fp_v8p_load(kfpu_t *fp)
618 #else /* lint */
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)
626 #endif /* lint */