2005-04-17 02:20:36 +04:00
/ *
*
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l P u b l i c
* License. S e e t h e f i l e " C O P Y I N G " i n t h e m a i n d i r e c t o r y o f t h i s a r c h i v e
* for m o r e d e t a i l s .
*
* Copyright ( C ) 2 0 0 0 H e w l e t t P a c k a r d ( P a u l B a m e b a m e @puffin.external.hp.com)
*
* /
2005-10-22 06:46:48 +04:00
# include < l i n u x / c o n f i g . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p s w . h >
2005-10-22 06:40:07 +04:00
# include < a s m / a s s e m b l y . h >
2005-04-17 02:20:36 +04:00
.section .bss
.export real_stack
.export real32_stack
.export real64_stack
.align 64
real_stack :
real32_stack :
real64_stack :
.block 8192
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
# define R E G _ S Z 8
# else
# define R E G _ S Z 4
# endif
# define N _ S A V E D _ R E G S 9
save_cr_space :
.block REG_SZ * N_ S A V E D _ R E G S
save_cr_end :
/************************ 32-bit real-mode calls ***********************/
/* This can be called in both narrow and wide kernels */
.text
.export real32_call_asm
/ * unsigned l o n g r e a l 3 2 _ c a l l _ a s m ( u n s i g n e d i n t * s p ,
* unsigned i n t * a r g 0 p ,
* unsigned i n t i o d c _ f n )
* sp i s v a l u e o f s t a c k p o i n t e r t o a d o p t b e f o r e c a l l i n g P D C ( v i r t )
* arg0 p p o i n t s t o w h e r e s a v e d a r g v a l u e s m a y b e f o u n d
* iodc_ f n i s t h e I O D C f u n c t i o n t o c a l l
* /
real32_call_asm :
STREG % r p , - R P _ O F F S E T ( % s p ) / * s a v e R P * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
callee_ s a v e
ldo 2 * R E G _ S Z ( % s p ) , % s p / * r o o m f o r a c o u p l e m o r e s a v e s * /
STREG % r27 , - 1 * R E G _ S Z ( % s p )
STREG % r29 , - 2 * R E G _ S Z ( % s p )
# endif
STREG % s p , - R E G _ S Z ( % a r g 0 ) / * s a v e S P o n r e a l - m o d e s t a c k * /
copy % a r g 0 , % s p / * a d o p t t h e r e a l - m o d e S P * /
/* save iodc_fn */
copy % a r g 2 , % r31
/* load up the arg registers from the saved arg area */
/* 32-bit calling convention passes first 4 args in registers */
ldw 0 ( % a r g 1 ) , % a r g 0 / * n o t e o v e r w r i t i n g a r g 0 * /
ldw - 8 ( % a r g 1 ) , % a r g 2
ldw - 1 2 ( % a r g 1 ) , % a r g 3
ldw - 4 ( % a r g 1 ) , % a r g 1 / * o b v i o u s l y m u s t d o t h i s o n e l a s t ! * /
tophys_ r1 % s p
b,l r f i _ v i r t 2 r e a l ,% r2
nop
b,l s a v e _ c o n t r o l _ r e g s ,% r2 / * m o d i f i e s r1 , r2 , r28 * /
nop
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
rsm P S W _ S M _ W , % r0 / * g o n a r r o w * /
# endif
load3 2 P A ( r i c _ r e t ) , % r2
bv 0 ( % r31 )
nop
ric_ret :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ssm P S W _ S M _ W , % r0 / * g o w i d e * /
# endif
/* restore CRs before going virtual in case we page fault */
b,l r e s t o r e _ c o n t r o l _ r e g s , % r2 / * m o d i f i e s r1 , r2 , r26 * /
nop
b,l r f i _ r e a l 2 v i r t ,% r2
nop
tovirt_ r1 % s p
LDREG - R E G _ S Z ( % s p ) , % s p / * r e s t o r e S P * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
LDREG - 1 * R E G _ S Z ( % s p ) , % r27
LDREG - 2 * R E G _ S Z ( % s p ) , % r29
ldo - 2 * R E G _ S Z ( % s p ) , % s p
callee_ r e s t
# endif
LDREG - R P _ O F F S E T ( % s p ) , % r p / * r e s t o r e R P * /
bv 0 ( % r p )
nop
# define P U S H _ C R ( r , w h e r e ) m f c t l r , % r1 ! S T R E G ,m a % r1 , R E G _ S Z ( w h e r e )
# define P O P _ C R ( r , w h e r e ) L D R E G ,m b - R E G _ S Z ( w h e r e ) , % r1 ! m t c t l % r1 , r
.text
save_control_regs :
load3 2 P A ( s a v e _ c r _ s p a c e ) , % r28
PUSH_ C R ( % c r24 , % r28 )
PUSH_ C R ( % c r25 , % r28 )
PUSH_ C R ( % c r26 , % r28 )
PUSH_ C R ( % c r27 , % r28 )
PUSH_ C R ( % c r28 , % r28 )
PUSH_ C R ( % c r29 , % r28 )
PUSH_ C R ( % c r30 , % r28 )
PUSH_ C R ( % c r31 , % r28 )
PUSH_ C R ( % c r15 , % r28 )
bv 0 ( % r2 )
nop
restore_control_regs :
load3 2 P A ( s a v e _ c r _ e n d ) , % r26
POP_ C R ( % c r15 , % r26 )
POP_ C R ( % c r31 , % r26 )
POP_ C R ( % c r30 , % r26 )
POP_ C R ( % c r29 , % r26 )
POP_ C R ( % c r28 , % r26 )
POP_ C R ( % c r27 , % r26 )
POP_ C R ( % c r26 , % r26 )
POP_ C R ( % c r25 , % r26 )
POP_ C R ( % c r24 , % r26 )
bv 0 ( % r2 )
nop
/ * rfi_ v i r t 2 r e a l ( ) a n d r f i _ r e a l 2 v i r t ( ) c o u l d p e r h a p s b e a d a p t e d f o r
* more g e n e r a l - p u r p o s e u s e b y t h e s e v e r a l p l a c e s w h i c h n e e d R F I s
* /
.align 128
.text
rfi_virt2real :
/* switch to real mode... */
2005-10-22 06:40:07 +04:00
rsm P S W _ S M _ I ,% r0
load3 2 P A ( r f i _ v2 r _ 1 ) , % r1
2005-04-17 02:20:36 +04:00
nop
nop
nop
nop
nop
2005-10-22 06:40:07 +04:00
rsm P S W _ S M _ Q ,% r0 / * d i s a b l e Q & I b i t s t o l o a d i i a q u e u e * /
2005-04-17 02:20:36 +04:00
mtctl % r0 , % c r17 / * C l e a r I I A S Q t a i l * /
mtctl % r0 , % c r17 / * C l e a r I I A S Q h e a d * /
mtctl % r1 , % c r18 / * I I A O Q h e a d * /
ldo 4 ( % r1 ) , % r1
mtctl % r1 , % c r18 / * I I A O Q t a i l * /
load3 2 R E A L _ M O D E _ P S W , % r1
mtctl % r1 , % c r22
rfi
nop
nop
nop
nop
nop
nop
nop
nop
rfi_v2r_1 :
tophys_ r1 % r2
bv 0 ( % r2 )
nop
.text
.align 128
rfi_real2virt :
2005-10-22 06:40:07 +04:00
rsm P S W _ S M _ I ,% r0
load3 2 ( r f i _ r2 v _ 1 ) , % r1
2005-04-17 02:20:36 +04:00
nop
nop
nop
nop
nop
rsm P S W _ S M _ Q ,% r0 / * d i s a b l e Q b i t t o l o a d i i a q u e u e * /
mtctl % r0 , % c r17 / * C l e a r I I A S Q t a i l * /
mtctl % r0 , % c r17 / * C l e a r I I A S Q h e a d * /
mtctl % r1 , % c r18 / * I I A O Q h e a d * /
ldo 4 ( % r1 ) , % r1
mtctl % r1 , % c r18 / * I I A O Q t a i l * /
load3 2 K E R N E L _ P S W , % r1
mtctl % r1 , % c r22
rfi
nop
nop
nop
nop
nop
nop
nop
nop
rfi_r2v_1 :
tovirt_ r1 % r2
bv 0 ( % r2 )
nop
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/************************ 64-bit real-mode calls ***********************/
/* This is only usable in wide kernels right now and will probably stay so */
.text
.export real64_call_asm
/ * unsigned l o n g r e a l 6 4 _ c a l l _ a s m ( u n s i g n e d l o n g * s p ,
* unsigned l o n g * a r g 0 p ,
* unsigned l o n g f n )
* sp i s v a l u e o f s t a c k p o i n t e r t o a d o p t b e f o r e c a l l i n g P D C ( v i r t )
* arg0 p p o i n t s t o w h e r e s a v e d a r g v a l u e s m a y b e f o u n d
* iodc_ f n i s t h e I O D C f u n c t i o n t o c a l l
* /
real64_call_asm :
std % r p , - 0 x10 ( % s p ) / * s a v e R P * /
std % s p , - 8 ( % a r g 0 ) / * s a v e S P o n r e a l - m o d e s t a c k * /
copy % a r g 0 , % s p / * a d o p t t h e r e a l - m o d e S P * /
/* save fn */
copy % a r g 2 , % r31
/* set up the new ap */
ldo 6 4 ( % a r g 1 ) , % r29
/* load up the arg registers from the saved arg area */
/* 32-bit calling convention passes first 4 args in registers */
ldd 0 * R E G _ S Z ( % a r g 1 ) , % a r g 0 / * n o t e o v e r w r i t i n g a r g 0 * /
ldd 2 * R E G _ S Z ( % a r g 1 ) , % a r g 2
ldd 3 * R E G _ S Z ( % a r g 1 ) , % a r g 3
ldd 4 * R E G _ S Z ( % a r g 1 ) , % r22
ldd 5 * R E G _ S Z ( % a r g 1 ) , % r21
ldd 6 * R E G _ S Z ( % a r g 1 ) , % r20
ldd 7 * R E G _ S Z ( % a r g 1 ) , % r19
ldd 1 * R E G _ S Z ( % a r g 1 ) , % a r g 1 / * d o t h i s o n e l a s t ! * /
tophys_ r1 % s p
b,l r f i _ v i r t 2 r e a l ,% r2
nop
b,l s a v e _ c o n t r o l _ r e g s ,% r2 / * m o d i f i e s r1 , r2 , r28 * /
nop
load3 2 P A ( r64 _ r e t ) , % r2
bv 0 ( % r31 )
nop
r64_ret :
/* restore CRs before going virtual in case we page fault */
b,l r e s t o r e _ c o n t r o l _ r e g s , % r2 / * m o d i f i e s r1 , r2 , r26 * /
nop
b,l r f i _ r e a l 2 v i r t ,% r2
nop
tovirt_ r1 % s p
ldd - 8 ( % s p ) , % s p / * r e s t o r e S P * /
ldd - 0 x10 ( % s p ) , % r p / * r e s t o r e R P * /
bv 0 ( % r p )
nop
# endif
.export pc_in_user_space
.text
/* Doesn't belong here but I couldn't find a nicer spot. */
/* Should never get called, only used by profile stuff in time.c */
pc_in_user_space :
bv,n 0 ( % r p )
nop
.export __canonicalize_funcptr_for_compare
.text
/ * http : / / lists. p a r i s c - l i n u x . o r g / h y p e r m a i l / p a r i s c - l i n u x / 1 0 9 1 6 . h t m l
* * GCC 3 . 3 a n d l a t e r h a s a n e w f u n c t i o n i n l i b g c c . a f o r
* * comparing f u n c t i o n p o i n t e r s .
* /
__canonicalize_funcptr_for_compare :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
bve ( % r2 )
# else
bv % r0 ( % r2 )
# endif
copy % r26 ,% r28