2005-04-16 15:20:36 -07: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 .
*
2007-01-24 22:36:32 +01:00
* Copyright ( C ) 1 9 9 9 - 2 0 0 7 b y H e l g e D e l l e r < d e l l e r @gmx.de>
2005-04-16 15:20:36 -07:00
* Copyright 1 9 9 9 S u S E G m b H ( P h i l i p p R u m p f )
* Copyright 1 9 9 9 P h i l i p p R u m p f ( p r u m p f @tux.org)
* Copyright 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)
* Copyright ( C ) 2 0 0 1 G r a n t G r u n d l e r ( H e w l e t t P a c k a r d )
* Copyright ( C ) 2 0 0 4 K y l e M c M a r t i n < k y l e @debian.org>
*
* Initial V e r s i o n 0 4 - 2 3 - 1 9 9 9 b y H e l g e D e l l e r < d e l l e r @gmx.de>
* /
2005-09-09 20:57:26 +02:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-16 15:20:36 -07:00
# include < a s m / p s w . h >
# include < a s m / p d c . h >
# include < a s m / a s s e m b l y . h >
# include < a s m / p g t a b l e . h >
2007-01-24 22:36:32 +01:00
# include < l i n u x / l i n k a g e . h >
2007-12-26 18:07:01 +01:00
# include < l i n u x / i n i t . h >
2007-01-24 22:36:32 +01:00
2005-04-16 15:20:36 -07:00
.level LEVEL
2007-12-26 18:07:01 +01:00
_ _ INITDATA
2007-01-24 22:36:32 +01:00
ENTRY( b o o t _ a r g s )
2005-04-16 15:20:36 -07:00
.word 0 /* arg0 */
.word 0 /* arg1 */
.word 0 /* arg2 */
.word 0 /* arg3 */
2007-01-24 22:36:32 +01:00
END( b o o t _ a r g s )
2005-04-16 15:20:36 -07:00
2008-05-22 14:38:26 -04:00
_ _ HEAD
2005-04-16 15:20:36 -07:00
.align 4
.import init_ t h r e a d _ u n i o n ,d a t a
.import fault_ v e c t o r _ 2 0 ,c o d e / * I V A p a r i s c 2 . 0 3 2 b i t * /
2005-10-21 22:46:48 -04:00
# ifndef C O N F I G _ 6 4 B I T
2005-04-16 15:20:36 -07:00
.import fault_ v e c t o r _ 1 1 ,c o d e / * I V A p a r i s c 1 . 1 3 2 b i t * /
.import $ global$ / * f o r w a r d d e c l a r a t i o n * /
2005-10-21 22:46:48 -04:00
# endif / * ! C O N F I G _ 6 4 B I T * /
2005-04-16 15:20:36 -07:00
.export _ stext,d a t a / * K e r n e l w a n t i t t h i s w a y ! * /
_stext :
2007-01-24 22:36:32 +01:00
ENTRY( s t e x t )
2005-04-16 15:20:36 -07:00
.proc
.callinfo
/* Make sure sr4-sr7 are set to zero for the kernel address space */
mtsp % r0 ,% s r4
mtsp % r0 ,% s r5
mtsp % r0 ,% s r6
mtsp % r0 ,% s r7
/* Clear BSS (shouldn't the boot loader do this?) */
.import _ _ bss_ s t a r t ,d a t a
.import _ _ bss_ s t o p ,d a t a
load3 2 P A ( _ _ b s s _ s t a r t ) ,% r3
load3 2 P A ( _ _ b s s _ s t o p ) ,% r4
$ bss_loop :
cmpb,< < ,n % r3 ,% r4 ,$ b s s _ l o o p
stw,m a % r0 ,4 ( % r3 )
/* Save away the arguments the boot loader passed in (32 bit args) */
load3 2 P A ( b o o t _ a r g s ) ,% r1
stw,m a % a r g 0 ,4 ( % r1 )
stw,m a % a r g 1 ,4 ( % r1 )
stw,m a % a r g 2 ,4 ( % r1 )
stw,m a % a r g 3 ,4 ( % r1 )
/* Initialize startup VM. Just map first 8/16 MB of memory */
load3 2 P A ( s w a p p e r _ p g _ d i r ) ,% r4
mtctl % r4 ,% c r24 / * I n i t i a l i z e k e r n e l r o o t p o i n t e r * /
mtctl % r4 ,% c r25 / * I n i t i a l i z e u s e r r o o t p o i n t e r * /
2006-04-20 20:40:23 +00:00
# if P T _ N L E V E L S = = 3
2005-04-16 15:20:36 -07:00
/* Set pmd in pgd */
load3 2 P A ( p m d0 ) ,% r5
shrd % r5 ,P x D _ V A L U E _ S H I F T ,% r3
2006-04-20 20:40:23 +00:00
ldo ( P x D _ F L A G _ P R E S E N T + P x D _ F L A G _ V A L I D ) ( % r3 ) ,% r3
2005-04-16 15:20:36 -07:00
stw % r3 ,A S M _ P G D _ E N T R Y * A S M _ P G D _ E N T R Y _ S I Z E ( % r4 )
ldo A S M _ P M D _ E N T R Y * A S M _ P M D _ E N T R Y _ S I Z E ( % r5 ) ,% r4
# else
/* 2-level page table, so pmd == pgd */
2006-04-20 20:40:23 +00:00
ldo A S M _ P G D _ E N T R Y * A S M _ P G D _ E N T R Y _ S I Z E ( % r4 ) ,% r4
2005-04-16 15:20:36 -07:00
# endif
/* Fill in pmd with enough pte directories */
load3 2 P A ( p g 0 ) ,% r1
SHRREG % r1 ,P x D _ V A L U E _ S H I F T ,% r3
ldo ( P x D _ F L A G _ P R E S E N T + P x D _ F L A G _ V A L I D ) ( % r3 ) ,% r3
ldi A S M _ P T _ I N I T I A L ,% r1
1 :
stw % r3 ,0 ( % r4 )
2007-10-18 00:04:43 -07:00
ldo ( P A G E _ S I Z E > > P x D _ V A L U E _ S H I F T ) ( % r3 ) ,% r3
2005-04-16 15:20:36 -07:00
addib,> - 1 ,% r1 ,1 b
2006-04-20 20:40:23 +00:00
# if P T _ N L E V E L S = = 3
2005-04-16 15:20:36 -07:00
ldo A S M _ P M D _ E N T R Y _ S I Z E ( % r4 ) ,% r4
# else
ldo A S M _ P G D _ E N T R Y _ S I Z E ( % r4 ) ,% r4
# endif
2011-04-14 18:25:21 -05:00
/ * Now i n i t i a l i z e t h e P T E s t h e m s e l v e s . W e u s e R W X f o r
* everything . . . i t w i l l g e t r e m a p p e d c o r r e c t l y l a t e r * /
ldo 0 + _ P A G E _ K E R N E L _ R W X ( % r0 ) ,% r3 / * H a r d w i r e d 0 p h y s a d d r s t a r t * /
2006-04-20 20:40:23 +00:00
ldi ( 1 < < ( K E R N E L _ I N I T I A L _ O R D E R - P A G E _ S H I F T ) ) ,% r11 / * P F N c o u n t * /
2005-04-16 15:20:36 -07:00
load3 2 P A ( p g 0 ) ,% r1
$ pgt_fill_loop :
STREGM % r3 ,A S M _ P T E _ E N T R Y _ S I Z E ( % r1 )
2006-04-20 20:40:23 +00:00
ldo ( 1 < < P F N _ P T E _ S H I F T ) ( % r3 ) ,% r3 / * a d d o n e P F N * /
addib,> - 1 ,% r11 ,$ p g t _ f i l l _ l o o p
2005-04-16 15:20:36 -07:00
nop
/* Load the return address...er...crash 'n burn */
copy % r0 ,% r2
/* And the RFI Target address too */
2008-07-29 00:11:13 -04:00
load3 2 s t a r t _ p a r i s c ,% r11
2005-04-16 15:20:36 -07:00
/* And the initial task pointer */
load3 2 i n i t _ t h r e a d _ u n i o n ,% r6
mtctl % r6 ,% c r30
/* And the stack pointer too */
ldo T H R E A D _ S Z _ A L G N ( % r6 ) ,% s p
# ifdef C O N F I G _ S M P
2011-03-30 22:57:33 -03:00
/ * Set t h e s m p r e n d e z v o u s a d d r e s s i n t o p a g e z e r o .
2005-04-16 15:20:36 -07:00
* * It w o u l d b e s a f e r t o d o t h i s i n i n i t _ s m p _ c o n f i g ( ) b u t
* * it' s j u s t w a y e a s i e r t o d e a l w i t h h e r e b e c a u s e
* * of 6 4 - b i t f u n c t i o n p t r s a n d t h e a d d r e s s i s l o c a l t o t h i s f i l e .
* /
load3 2 P A ( s m p _ s l a v e _ s t e x t ) ,% r10
stw % r10 ,0 x10 ( % r0 ) / * M E M _ R E N D E Z * /
stw % r0 ,0 x28 ( % r0 ) / * M E M _ R E N D E Z _ H I - a s s u m e a d d r < 4 G B * /
/* FALLTHROUGH */
.procend
/ *
* * Code C o m m o n t o b o t h M o n a r c h a n d S l a v e p r o c e s s o r s .
* * Entry :
* *
* * 1 .1 :
* * % r1 1 m u s t c o n t a i n R F I t a r g e t a d d r e s s .
* * % r2 5 / % r26 a r g s t o p a s s t o t a r g e t f u n c t i o n
* * % r2 i n c a s e r f i t a r g e t d e c i d e s i t d i d n ' t l i k e s o m e t h i n g
* *
* * 2 .0w :
* * % r3 P D C E _ P R O C a d d r e s s
* * % r1 1 R F I t a r g e t a d d r e s s
* *
* * Caller m u s t i n i t : S R 4 - 7 , % s p , % r10 , % c r24 / 2 5 ,
* /
common_stext :
.proc
.callinfo
# else
/* Clear PDC entry point - we won't use it */
stw % r0 ,0 x10 ( % r0 ) / * M E M _ R E N D E Z * /
stw % r0 ,0 x28 ( % r0 ) / * M E M _ R E N D E Z _ H I * /
# endif / * C O N F I G _ S M P * /
2005-10-21 22:46:48 -04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-16 15:20:36 -07:00
tophys_ r1 % s p
/* Save the rfi target address */
ldd T I _ T A S K - T H R E A D _ S Z _ A L G N ( % s p ) , % r10
tophys_ r1 % r10
std % r11 , T A S K _ P T _ G R 1 1 ( % r10 )
/ * Switch t o w i d e m o d e S u p e r d o m e d o e s n ' t s u p p o r t n a r r o w P D C
* * calls.
* /
1 : mfia % r p / * c l e a r u p p e r p a r t o f p c o q * /
ldo 2 f - 1 b ( % r p ) ,% r p
depdi 0 ,3 1 ,3 2 ,% r p
bv ( % r p )
ssm P S W _ S M _ W ,% r0
/ * Set W i d e m o d e a s t h e " D e f a u l t " ( e g f o r t r a p s )
* * First t r a p o c c u r s * r i g h t * a f t e r ( o r p a r t o f ) r f i f o r s l a v e C P U s .
* * Someday, p a l o m i g h t n o t d o t h i s f o r t h e M o n a r c h e i t h e r .
* /
2 :
# define M E M _ P D C _ L O 0 x38 8
# define M E M _ P D C _ H I 0 x35 C
ldw M E M _ P D C _ L O ( % r0 ) ,% r3
ldw M E M _ P D C _ H I ( % r0 ) ,% r6
depd % r6 , 3 1 , 3 2 , % r3 / * m o v e t o u p p e r w o r d * /
ldo P D C _ P S W ( % r0 ) ,% a r g 0 / * 2 1 * /
ldo P D C _ P S W _ S E T _ D E F A U L T S ( % r0 ) ,% a r g 1 / * 2 * /
ldo P D C _ P S W _ W I D E _ B I T ( % r0 ) ,% a r g 2 / * 2 * /
load3 2 P A ( s t e x t _ p d c _ r e t ) , % r p
bv ( % r3 )
copy % r0 ,% a r g 3
stext_pdc_ret :
/* restore rfi target address*/
ldd T I _ T A S K - T H R E A D _ S Z _ A L G N ( % s p ) , % r10
tophys_ r1 % r10
ldd T A S K _ P T _ G R 1 1 ( % r10 ) , % r11
tovirt_ r1 % s p
# endif
/* PARANOID: clear user scratch/user space SR's */
mtsp % r0 ,% s r0
mtsp % r0 ,% s r1
mtsp % r0 ,% s r2
mtsp % r0 ,% s r3
/* Initialize Protection Registers */
mtctl % r0 ,% c r8
mtctl % r0 ,% c r9
mtctl % r0 ,% c r12
mtctl % r0 ,% c r13
/* Initialize the global data pointer */
loadgp
/ * Set u p o u r i n t e r r u p t t a b l e . H P M C s m i g h t n o t w o r k a f t e r t h i s !
*
* We n e e d t o i n s t a l l t h e c o r r e c t i v a f o r P A 1 . 1 o r P A 2 . 0 . T h e
* following s h o r t s e q u e n c e o f i n s t r u c t i o n s c a n d e t e r m i n e t h i s
* ( without b e i n g i l l e g a l o n a P A 1 . 1 m a c h i n e ) .
* /
2005-10-21 22:46:48 -04:00
# ifndef C O N F I G _ 6 4 B I T
2005-04-16 15:20:36 -07:00
ldi 3 2 ,% r10
mtctl % r10 ,% c r11
.level 2 .0
mfctl,w % c r11 ,% r10
.level 1 .1
comib,< > ,n 0 ,% r10 ,$ i s _ p a20
ldil L % P A ( f a u l t _ v e c t o r _ 1 1 ) ,% r10
b $ i n s t a l l _ i v a
ldo R % P A ( f a u l t _ v e c t o r _ 1 1 ) ( % r10 ) ,% r10
$ is_pa20 :
.level LEVEL /* restore 1.1 || 2.0w */
2005-10-21 22:46:48 -04:00
# endif / * ! C O N F I G _ 6 4 B I T * /
2005-04-16 15:20:36 -07:00
load3 2 P A ( f a u l t _ v e c t o r _ 2 0 ) ,% r10
$ install_iva :
mtctl % r10 ,% c r14
2005-10-21 22:40:07 -04:00
b a l i g n e d _ r f i / * P r e p a r e t o R F I ! M a n a l l t h e c a n n o n s ! * /
2005-04-16 15:20:36 -07:00
nop
2005-10-21 22:40:07 -04:00
.align 128
2005-04-16 15:20:36 -07:00
aligned_rfi :
2005-10-21 22:40:07 -04:00
pcxt_ s s m _ b u g
2005-04-16 15:20:36 -07:00
2005-10-21 22:40:07 -04:00
rsm P S W _ S M _ Q U I E T ,% r0 / * o f f t r o u b l e s o m e P S W b i t s * /
/* Don't need NOPs, have 8 compliant insn before rfi */
2005-04-16 15:20:36 -07: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 * /
/* Load RFI target into PC queue */
mtctl % r11 ,% c r18 / * I I A O Q h e a d * /
ldo 4 ( % r11 ) ,% r11
mtctl % r11 ,% c r18 / * I I A O Q t a i l * /
2005-10-21 22:40:07 -04:00
load3 2 K E R N E L _ P S W ,% r10
mtctl % r10 ,% i p s w
2005-04-16 15:20:36 -07:00
2005-10-21 22:40:07 -04:00
/* Jump through hyperspace to Virt Mode */
2005-04-16 15:20:36 -07:00
rfi
nop
.procend
# ifdef C O N F I G _ S M P
.import smp_ i n i t _ c u r r e n t _ i d l e _ t a s k ,d a t a
.import smp_ c a l l i n ,c o d e
2005-10-21 22:46:48 -04:00
# ifndef C O N F I G _ 6 4 B I T
2005-04-16 15:20:36 -07:00
smp_callin_rtn :
.proc
.callinfo
break 1 ,1 / * B r e a k i f r e t u r n e d f r o m s t a r t _ s e c o n d a r y * /
nop
nop
.procend
2005-10-21 22:46:48 -04:00
# endif / * ! C O N F I G _ 6 4 B I T * /
2005-04-16 15:20:36 -07:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* smp_ s l a v e _ s t e x t i s e x e c u t e d b y a l l n o n - m o n a r c h P r o c e s s o r s w h e n t h e M o n a r c h
* pokes t h e s l a v e C P U s i n s m p . c : s m p _ b o o t _ c p u s ( ) .
*
* Once h e r e , r e g i s t e r s v a l u e s a r e i n i t i a l i z e d i n o r d e r t o b r a n c h t o v i r t u a l
* mode. O n c e a l l a v a i l a b l e / e l i g i b l e C P U s a r e i n v i r t u a l m o d e , a l l a r e
* released a n d s t a r t o u t b y e x e c u t i n g t h e i r o w n i d l e t a s k .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
smp_slave_stext :
.proc
.callinfo
/ *
* * Initialize S p a c e r e g i s t e r s
* /
mtsp % r0 ,% s r4
mtsp % r0 ,% s r5
mtsp % r0 ,% s r6
mtsp % r0 ,% s r7
/* Initialize the SP - monarch sets up smp_init_current_idle_task */
load3 2 P A ( s m p _ i n i t _ c u r r e n t _ i d l e _ t a s k ) ,% s p
LDREG 0 ( % s p ) ,% s p / * l o a d t a s k a d d r e s s * /
tophys_ r1 % s p
LDREG T A S K _ T H R E A D _ I N F O ( % s p ) ,% s p
mtctl % s p ,% c r30 / * s t o r e i n c r30 * /
ldo T H R E A D _ S Z _ A L G N ( % s p ) ,% s p
/* point CPU to kernel page tables */
load3 2 P A ( s w a p p e r _ p g _ d i r ) ,% r4
mtctl % r4 ,% c r24 / * I n i t i a l i z e k e r n e l r o o t p o i n t e r * /
mtctl % r4 ,% c r25 / * I n i t i a l i z e u s e r r o o t p o i n t e r * /
2005-10-21 22:46:48 -04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-16 15:20:36 -07:00
/* Setup PDCE_PROC entry */
copy % a r g 0 ,% r3
# else
/* Load RFI *return* address in case smp_callin bails */
load3 2 s m p _ c a l l i n _ r t n ,% r2
# endif
/* Load RFI target address. */
load3 2 s m p _ c a l l i n ,% r11
/* ok...common code can handle the rest */
b c o m m o n _ s t e x t
nop
.procend
# endif / * C O N F I G _ S M P * /
2007-01-24 22:36:32 +01:00
ENDPROC( s t e x t )
2005-10-21 22:46:48 -04:00
# ifndef C O N F I G _ 6 4 B I T
2010-02-20 01:03:44 +01:00
.section .data . .read_mostly
2005-04-16 15:20:36 -07:00
.align 4
.export $ global$ ,d a t a
.type $ global$ ,@object
.size $ global$ ,4
$ global$ :
.word 0
2005-10-21 22:46:48 -04:00
# endif / * ! C O N F I G _ 6 4 B I T * /