2008-05-19 16:53:02 -07:00
/ *
2005-04-16 15:20:36 -07:00
* head. S : T h e i n i t i a l b o o t c o d e f o r t h e S p a r c p o r t o f L i n u x .
*
* Copyright ( C ) 1 9 9 5 D a v i d S . M i l l e r ( d a v e m @caip.rutgers.edu)
* Copyright ( C ) 1 9 9 5 ,1 9 9 9 P e t e Z a i t c e v ( z a i t c e v @yahoo.com)
* Copyright ( C ) 1 9 9 6 M i g u e l d e I c a z a ( m i g u e l @nuclecu.unam.mx)
* Copyright ( C ) 1 9 9 7 J a k u b J e l i n e k ( j j @sunsite.mff.cuni.cz)
* Copyright ( C ) 1 9 9 7 M i c h a e l A . G r i f f i t h ( g r i f @acm.org)
*
* CompactPCI p l a t f o r m b y E r i c B r o w e r , 1 9 9 9 .
* /
# include < l i n u x / v e r s i o n . h >
# include < l i n u x / i n i t . h >
# include < a s m / h e a d . h >
# include < a s m / a s i . h >
# include < a s m / c o n t r e g s . h >
# include < a s m / p t r a c e . h >
# include < a s m / p s r . h >
# include < a s m / p a g e . h >
2007-05-14 03:22:08 -07:00
# include < a s m / k d e b u g . h >
2005-04-16 15:20:36 -07:00
# include < a s m / w i n m a c r o . h >
# include < a s m / t h r e a d _ i n f o . h > / * T I _ U W I N M A S K * /
# include < a s m / e r r n o . h >
# include < a s m / p g t s r m m u . h > / * S R M M U _ P G D I R _ S H I F T * /
.data
2012-05-12 01:43:48 +00:00
/ * The f o l l o w i n g a r e u s e d w i t h t h e p r o m _ v e c t o r n o d e - o p s t o f i g u r e o u t
* the c p u - t y p e
2005-04-16 15:20:36 -07:00
* /
.align 4
.globl cputypval
cputypval :
2012-05-12 01:43:48 +00:00
.asciz " sun4 m "
2005-04-16 15:20:36 -07:00
.ascii " "
2012-05-12 01:43:48 +00:00
/* Tested on SS-5, SS-10 */
2005-04-16 15:20:36 -07:00
.align 4
cputypvar :
.asciz " compatible"
.align 4
2012-05-25 21:20:05 +00:00
notsup :
.asciz " Sparc- L i n u x s u n 4 / s u n 4 c o r M M U - l e s s n o t s u p p o r t e d \ n \ n "
2005-04-16 15:20:36 -07:00
.align 4
sun4e_notsup :
.asciz " Sparc- L i n u x s u n 4 e s u p p o r t d o e s n o t e x i s t \ n \ n "
.align 4
2012-05-19 20:02:45 +00:00
/* The trap-table - located in the __HEAD section */
# include " t t a b l e _ 3 2 . S "
2012-05-11 11:35:04 +00:00
2005-04-16 15:20:36 -07:00
.align PAGE_SIZE
/ * This w a s t h e o n l y r e a s o n a b l e w a y I c o u l d t h i n k o f t o p r o p e r l y a l i g n
* these p a g e - t a b l e d a t a s t r u c t u r e s .
* /
2012-05-12 01:43:46 +00:00
.globl empty_zero_page
2005-04-16 15:20:36 -07:00
empty_zero_page : .skip P A G E _ S I Z E
.global root_flags
.global ram_flags
.global root_dev
.global sparc_ramdisk_image
.global sparc_ramdisk_size
/ * This s t u f f h a s t o b e i n s y n c w i t h S I L O a n d o t h e r p o t e n t i a l b o o t l o a d e r s
* Fields s h o u l d b e k e p t u p w a r d c o m p a t i b l e a n d w h e n e v e r a n y c h a n g e i s m a d e ,
* HdrS v e r s i o n s h o u l d b e i n c r e m e n t e d .
* /
.ascii " HdrS"
.word LINUX_VERSION_CODE
.half 0x0203 /* HdrS version */
root_flags :
.half 1
root_dev :
.half 0
ram_flags :
.half 0
sparc_ramdisk_image :
.word 0
sparc_ramdisk_size :
.word 0
.word reboot_command
.word 0 , 0 , 0
.word _end
/ * Cool, h e r e w e g o . P i c k u p t h e r o m v e c p o i n t e r i n % o 0 a n d s t a s h i t i n
* % g7 a n d a t p r o m _ v e c t o r _ p . A n d a l s o q u i c k l y c h e c k w h e t h e r w e a r e o n
* a v0 , v2 , o r v3 p r o m .
* /
gokernel :
/ * Ok, i t ' s n i c e t o k n o w , a s e a r l y a s p o s s i b l e , i f w e
* are a l r e a d y m a p p e d w h e r e w e e x p e c t t o b e i n v i r t u a l
* memory. T h e S o l a r i s / b o o t e l f f o r m a t b o o t l o a d e r
* will p e e k i n t o o u r e l f h e a d e r a n d l o a d u s w h e r e
* we w a n t t o b e , o t h e r w i s e w e h a v e t o r e - m a p .
*
* Some b o o t l o a d e r s d o n ' t p l a c e t h e j m p ' r s a d d r e s s
* in % o 7 , s o w e d o a p c - r e l a t i v e c a l l t o a l o c a l
* label, t h e n s e e w h a t % o 7 h a s .
* /
mov % o 7 , % g 4 ! S a v e % o 7
/* Jump to it, and pray... */
current_pc :
call 1 f
nop
1 :
mov % o 7 , % g 3
tst % o 0
be n o _ s u n 4 u _ h e r e
mov % g 4 , % o 7 / * P r e v i o u s % o 7 . * /
2012-05-25 21:20:05 +00:00
2005-04-16 15:20:36 -07:00
mov % o 0 , % l 0 ! s t a s h a w a y r o m v e c
mov % o 0 , % g 7 ! p u t i t h e r e t o o
mov % o 1 , % l 1 ! s t a s h a w a y d e b u g _ v e c t o o
/* Ok, let's check out our run time program counter. */
set c u r r e n t _ p c , % g 5
cmp % g 3 , % g 5
be a l r e a d y _ m a p p e d
2012-05-25 21:20:05 +00:00
nop
2005-04-16 15:20:36 -07:00
/ * % l6 w i l l h o l d t h e o f f s e t w e h a v e t o s u b t r a c t
* from a b s o l u t e s y m b o l s i n o r d e r t o a c c e s s a r e a s
* in o u r o w n i m a g e . I f a l r e a d y m a p p e d t h i s i s
* just p l a i n z e r o , e l s e i t i s K E R N B A S E .
* /
set K E R N B A S E , % l 6
b c o p y _ p r o m _ l v l 1 4
nop
already_mapped :
mov 0 , % l 6
/* Copy over the Prom's level 14 clock handler. */
copy_prom_lvl14 :
# if 1
/ * DJHR
* preserve o u r l i n k e d / c a l c u l a t e d i n s t r u c t i o n s
* /
set l v l 1 4 _ s a v e , % g 1
set t _ i r q14 , % g 3
sub % g 1 , % l 6 , % g 1 ! t r a n s l a t e t o p h y s i c a l
sub % g 3 , % l 6 , % g 3 ! t r a n s l a t e t o p h y s i c a l
ldd [ % g 3 ] , % g 4
std % g 4 , [ % g 1 ]
ldd [ % g 3 + 8 ] , % g 4
std % g 4 , [ % g 1 + 8 ]
# endif
rd % t b r , % g 1
andn % g 1 , 0 x f f f , % g 1 ! p r o m s t r a p t a b l e b a s e
or % g 0 , ( 0 x1 e < < 4 ) , % g 2 ! o f f s e t t o l v l 1 4 i n t r
or % g 1 , % g 2 , % g 2
set t _ i r q14 , % g 3
sub % g 3 , % l 6 , % g 3
ldd [ % g 2 ] , % g 4
std % g 4 , [ % g 3 ]
ldd [ % g 2 + 0 x8 ] , % g 4
std % g 4 , [ % g 3 + 0 x8 ] ! C o p y p r o m s h a n d l e r
2012-05-11 11:35:15 +00:00
/ * DON' T T O U C H % l 0 t h r u % l 5 i n t h e s e r e m a p p i n g r o u t i n e s ,
* we n e e d t h e i r v a l u e s a f t e r w a r d s !
2005-04-16 15:20:36 -07:00
* /
2012-05-11 11:35:15 +00:00
2005-04-16 15:20:36 -07:00
/ * Now c h e c k w h e t h e r w e a r e a l r e a d y m a p p e d , i f w e
* are w e c a n s k i p a l l t h i s g a r b a g e c o m i n g u p .
* /
copy_prom_done :
cmp % l 6 , 0
be g o _ t o _ h i g h m e m ! t h i s w i l l b e a n o p t h e n
nop
2012-05-12 01:02:11 -07:00
/ * Validate t h a t w e a r e i n f a c t r u n n i n g o n a n
* SRMMU b a s e d c p u .
* /
set 0 x40 0 0 , % g 6
cmp % g 7 , % g 6
bne n o t _ a _ s u n 4
nop
2012-05-25 21:20:06 +00:00
halt_notsup :
2012-05-12 01:02:11 -07:00
ld [ % g 7 + 0 x68 ] , % o 1
2012-05-25 21:20:05 +00:00
set n o t s u p , % o 0
2012-05-12 01:02:11 -07:00
sub % o 0 , % l 6 , % o 0
call % o 1
nop
ba h a l t _ m e
nop
not_a_sun4 :
2012-05-25 21:20:06 +00:00
/ * It l o o k s l i k e t h i s i s a m a c h i n e w e s u p p o r t .
* Now f i n d o u t w h a t M M U w e a r e d e a l i n g w i t h
* LEON - i d e n t i f i e d b y t h e p s r . i m p l f i e l d
* Viking - i d e n t i f i e d b y t h e p s r . i m p l f i e l d
* In a l l o t h e r c a s e s a s u n 4 m s r m m u .
* We c h e c k t h a t t h e M M U i s e n a b l e d i n a l l c a s e s .
* /
/* Check if this is a LEON CPU */
rd % p s r , % g 3
srl % g 3 , P S R _ I M P L _ S H I F T , % g 3
and % g 3 , P S R _ I M P L _ S H I F T E D _ M A S K , % g 3
cmp % g 3 , P S R _ I M P L _ L E O N
be l e o n _ r e m a p / * I t i s a L E O N - j u m p * /
nop
/* Sanity-check, is MMU enabled */
2012-05-12 01:02:11 -07:00
lda [ % g 0 ] A S I _ M _ M M U R E G S , % g 1
andcc % g 1 , 1 , % g 0
2012-05-25 21:20:06 +00:00
be h a l t _ n o t s u p
2012-05-12 01:02:11 -07:00
nop
2012-05-25 21:20:06 +00:00
/* Check for a viking (TI) module. */
cmp % g 3 , P S R _ I M P L _ T I
bne s r m m u _ n o t _ v i k i n g
2005-04-16 15:20:36 -07:00
nop
/ * Figure o u t w h a t k i n d o f v i k i n g w e a r e o n .
* We n e e d t o k n o w i f w e h a v e t o p l a y w i t h t h e
* AC b i t a n d d i s a b l e t r a p s o r n o t .
* /
/ * I' v e o n l y s e e n M i c r o S p a r c ' s o n S p a r c C l a s s i c s w i t h t h i s
* bit s e t .
* /
set 0 x80 0 , % g 2
lda [ % g 0 ] A S I _ M _ M M U R E G S , % g 3 ! p e e k i n t h e c o n t r o l r e g
and % g 2 , % g 3 , % g 3
subcc % g 3 , 0 x0 , % g 0
2012-05-25 21:20:06 +00:00
bnz s r m m u _ n o t _ v i k i n g ! i s i n m b u s m o d e
2005-04-16 15:20:36 -07:00
nop
2012-05-25 21:20:05 +00:00
2005-04-16 15:20:36 -07:00
rd % p s r , % g 3 ! D O N O T T O U C H % g 3
andn % g 3 , P S R _ E T , % g 2
wr % g 2 , 0 x0 , % p s r
WRITE_ P A U S E
2012-05-25 21:20:05 +00:00
2005-04-16 15:20:36 -07:00
/ * Get c o n t e x t t a b l e p o i n t e r , t h e n c o n v e r t t o
* a p h y s i c a l a d d r e s s , w h i c h i s 3 6 b i t s .
* /
set A C _ M _ C T P R , % g 4
lda [ % g 4 ] A S I _ M _ M M U R E G S , % g 4
sll % g 4 , 0 x4 , % g 4 ! W e u s e t h i s b e l o w
! DO N O T T O U C H % g 4
/* Set the AC bit in the Viking's MMU control reg. */
lda [ % g 0 ] A S I _ M _ M M U R E G S , % g 5 ! D O N O T T O U C H % g 5
set 0 x80 0 0 , % g 6 ! A C b i t m a s k
or % g 5 , % g 6 , % g 6 ! O r i t i n . . .
sta % g 6 , [ % g 0 ] A S I _ M _ M M U R E G S ! C l o s e y o u r e y e s . . .
/ * Grrr, w h y d o e s i t s e e m l i k e e v e r y o t h e r l o a d / s t o r e
* on t h e s u n 4 m i s i n s o m e A S I s p a c e . . .
* Fine w i t h m e , l e t ' s g e t t h e p o i n t e r t o t h e l e v e l 1
* page t a b l e d i r e c t o r y a n d f e t c h i t s e n t r y .
* /
lda [ % g 4 ] A S I _ M _ B Y P A S S , % o 1 ! T h i s i s a l e v e l 1 p t r
srl % o 1 , 0 x4 , % o 1 ! C l e a r l o w 4 b i t s
sll % o 1 , 0 x8 , % o 1 ! M a k e p h y s i c a l
2012-05-25 21:20:05 +00:00
2005-04-16 15:20:36 -07:00
/* Ok, pull in the PTD. */
lda [ % o 1 ] A S I _ M _ B Y P A S S , % o 2 ! T h i s i s t h e 0 x0 1 6 M B p g d
/* Calculate to KERNBASE entry. */
2012-05-25 21:20:05 +00:00
add % o 1 , K E R N B A S E > > ( S R M M U _ P G D I R _ S H I F T - 2 ) , % o 3
2005-04-16 15:20:36 -07:00
/* Poke the entry into the calculated address. */
sta % o 2 , [ % o 3 ] A S I _ M _ B Y P A S S
/ * I d o n ' t g e t i t S u n , i f y o u e n g i n e e r e d a l l t h e s e
* boot l o a d e r s a n d t h e P R O M ( t h a n k y o u f o r t h e d e b u g g i n g
* features b t w ) w h y d i d y o u n o t h a v e t h e m l o a d k e r n e l
* images u p i n h i g h a d d r e s s s p a c e , s i n c e t h i s i s n e c e s s a r y
* for A B I c o m p l i a n c e a n y w a y s ? D o e s t h i s l o w - m a p p i n g p r o v i d e
* enhanced i n t e r o p e r a b i l i t y ?
*
* " The P R O M i s t h e c o m p u t e r . "
* /
/* Ok, restore the MMU control register we saved in %g5 */
sta % g 5 , [ % g 0 ] A S I _ M _ M M U R E G S ! P O W . . . o u c h
/* Turn traps back on. We saved it in %g3 earlier. */
wr % g 3 , 0 x0 , % p s r ! t i c k t o c k , t i c k t o c k
/* Now we burn precious CPU cycles due to bad engineering. */
WRITE_ P A U S E
/ * Wow, a l l t h a t j u s t t o m o v e a 3 2 - b i t v a l u e f r o m o n e
* place t o a n o t h e r . . . J u m p t o h i g h m e m o r y .
* /
b g o _ t o _ h i g h m e m
nop
2012-05-25 21:20:06 +00:00
srmmu_not_viking :
2005-04-16 15:20:36 -07:00
/ * This w o r k s o n v i k i n g ' s i n M b u s m o d e a n d a l l
* other M B U S m o d u l e s . I t i s v i r t u a l l y t h e s a m e a s
* the a b o v e m a d n e s s s a n s t u r n i n g t r a p s o f f a n d f l i p p i n g
* the A C b i t .
* /
set A C _ M _ C T P R , % g 1
lda [ % g 1 ] A S I _ M _ M M U R E G S , % g 1 ! g e t c t x t a b l e p t r
sll % g 1 , 0 x4 , % g 1 ! m a k e p h y s i c a l a d d r
lda [ % g 1 ] A S I _ M _ B Y P A S S , % g 1 ! p t r t o l e v e l 1 p g _ t a b l e
srl % g 1 , 0 x4 , % g 1
sll % g 1 , 0 x8 , % g 1 ! m a k e p h y s a d d r f o r l 1 t b l
lda [ % g 1 ] A S I _ M _ B Y P A S S , % g 2 ! g e t l e v e l 1 e n t r y f o r 0 x0
add % g 1 , K E R N B A S E > > ( S R M M U _ P G D I R _ S H I F T - 2 ) , % g 3
sta % g 2 , [ % g 3 ] A S I _ M _ B Y P A S S ! p l a c e a t K E R N B A S E e n t r y
b g o _ t o _ h i g h m e m
nop ! w h e e e . . . .
2012-05-25 21:20:06 +00:00
leon_remap :
/* Sanity-check, is MMU enabled */
lda [ % g 0 ] A S I _ L E O N _ M M U R E G S , % g 1
andcc % g 1 , 1 , % g 0
be h a l t _ n o t s u p
nop
/ * Same c o d e a s i n t h e s r m m u _ n o t _ v i k i n g c a s e ,
* with t h e L E O N A S I f o r m m u r e g s
* /
set A C _ M _ C T P R , % g 1
lda [ % g 1 ] A S I _ L E O N _ M M U R E G S , % g 1 ! g e t c t x t a b l e p t r
sll % g 1 , 0 x4 , % g 1 ! m a k e p h y s i c a l a d d r
lda [ % g 1 ] A S I _ M _ B Y P A S S , % g 1 ! p t r t o l e v e l 1 p g _ t a b l e
srl % g 1 , 0 x4 , % g 1
sll % g 1 , 0 x8 , % g 1 ! m a k e p h y s a d d r f o r l 1 t b l
lda [ % g 1 ] A S I _ M _ B Y P A S S , % g 2 ! g e t l e v e l 1 e n t r y f o r 0 x0
add % g 1 , K E R N B A S E > > ( S R M M U _ P G D I R _ S H I F T - 2 ) , % g 3
sta % g 2 , [ % g 3 ] A S I _ M _ B Y P A S S ! p l a c e a t K E R N B A S E e n t r y
b g o _ t o _ h i g h m e m
nop ! w h e e e . . . .
2005-04-16 15:20:36 -07:00
/* Now do a non-relative jump so that PC is in high-memory */
go_to_highmem :
set e x e c u t e _ i n _ h i g h _ m e m , % g 1
jmpl % g 1 , % g 0
nop
/ * The c o d e a b o v e s h o u l d b e a t b e g i n n i n g a n d w e h a v e t o t a k e c a r e a b o u t
2009-04-27 14:02:26 -04:00
* short j u m p s , a s b r a n c h i n g t o . i n i t . t e x t s e c t i o n f r o m . t e x t i s u s u a l l y
2005-04-16 15:20:36 -07:00
* impossible * /
_ _ INIT
/ * Acquire b o o t t i m e p r i v i l e g e d r e g i s t e r v a l u e s , t h i s w i l l h e l p d e b u g g i n g .
* I f i g u r e o u t a n d s t o r e n w i n d o w s a n d n w i n d o w s m 1 l a t e r o n .
* /
execute_in_high_mem :
mov % l 0 , % o 0 ! p u t b a c k r o m v e c
mov % l 1 , % o 1 ! a n d d e b u g _ v e c
sethi % h i ( p r o m _ v e c t o r _ p ) , % g 1
st % o 0 , [ % g 1 + % l o ( p r o m _ v e c t o r _ p ) ]
sethi % h i ( l i n u x _ d b v e c ) , % g 1
st % o 1 , [ % g 1 + % l o ( l i n u x _ d b v e c ) ]
2012-05-29 08:14:12 +00:00
/ * Get t h e m a c h i n e t y p e v i a t h e r o m v e c
* getprops n o d e o p e r a t i o n
2012-05-25 21:20:07 +00:00
* /
add % g 7 , 0 x1 c , % l 1
ld [ % l 1 ] , % l 0
ld [ % l 0 ] , % l 0
call % l 0
or % g 0 , % g 0 , % o 0 ! n e x t _ n o d e ( 0 ) = f i r s t _ n o d e
or % o 0 , % g 0 , % g 6
sethi % h i ( c p u t y p v a r ) , % o 1 ! F i r s t n o d e h a s c p u - a r c h
or % o 1 , % l o ( c p u t y p v a r ) , % o 1
sethi % h i ( c p u t y p v a l ) , % o 2 ! i n f o r m a t i o n , t h e s t r i n g
or % o 2 , % l o ( c p u t y p v a l ) , % o 2
ld [ % l 1 ] , % l 0 ! ' c o m p a t i b l e ' t e l l s
ld [ % l 0 + 0 x c ] , % l 0 ! t h a t w e w a n t ' s u n 4 x ' w h e r e
call % l 0 ! x i s o n e o f ' m ' , ' d ' o r ' e ' .
nop ! % o 2 h o l d s p o i n t e r
! to a b u f w h e r e a b o v e s t r i n g
! will g e t s t o r e d b y t h e p r o m .
2012-05-12 01:43:49 +00:00
2012-05-29 08:14:12 +00:00
/ * Check v a l u e o f " c o m p a t i b l e " p r o p e r t y .
* " value" = > " m o d e l "
* leon = > s p a r c _ l e o n
* sun4 m = > s u n 4 m
* sun4 s = > s u n 4 m
* sun4 d = > s u n 4 d
* sun4 e = > " n o _ s u n 4 e _ h e r e "
* ' * ' = > " no_ s u n 4 u _ h e r e "
* Check s i n g l e l e t t e r s o n l y
* /
2005-04-16 15:20:36 -07:00
set c p u t y p v a l , % o 2
2012-05-29 08:14:12 +00:00
/* If cputypval[0] == 'l' (lower case letter L) this is leon */
ldub [ % o 2 ] , % l 1
cmp % l 1 , ' l '
be l e o n _ i n i t
nop
/* Check cputypval[4] to find the sun model */
2005-04-16 15:20:36 -07:00
ldub [ % o 2 + 0 x4 ] , % l 1
2012-05-12 01:43:49 +00:00
cmp % l 1 , ' m '
be s u n 4 m _ i n i t
2005-04-16 15:20:36 -07:00
cmp % l 1 , ' s '
2012-05-12 01:43:49 +00:00
be s u n 4 m _ i n i t
2005-04-16 15:20:36 -07:00
cmp % l 1 , ' d '
2012-05-12 01:43:49 +00:00
be s u n 4 d _ i n i t
2005-04-16 15:20:36 -07:00
cmp % l 1 , ' e '
be n o _ s u n 4 e _ h e r e ! C o u l d b e a s u n 4 e .
nop
b n o _ s u n 4 u _ h e r e ! A I E E E , a V 9 s u n 4 u . . . G e t o u r B I G B R O T H E R k e r n e l : ) )
nop
2012-05-29 08:14:12 +00:00
leon_init :
/* LEON CPU - set boot_cpu_id */
sethi % h i ( b o o t _ c p u _ i d ) , % g 2 ! b o o t - c p u i n d e x
# ifdef C O N F I G _ S M P
ldub [ % g 2 + % l o ( b o o t _ c p u _ i d ) ] , % g 1
cmp % g 1 , 0 x f f ! u n s e t m e a n s f i r s t C P U
bne l e o n _ s m p _ c p u _ s t a r t u p ! c o n t i n u e o n l y w i t h m a s t e r
nop
# endif
/* Get CPU-ID from most significant 4-bit of ASR17 */
rd % a s r17 , % g 1
srl % g 1 , 2 8 , % g 1
/* Update boot_cpu_id only on boot cpu */
stub % g 1 , [ % g 2 + % l o ( b o o t _ c p u _ i d ) ]
ba c o n t i n u e _ b o o t
nop
2005-04-16 15:20:36 -07:00
/* CPUID in bootbus can be found at PA 0xff0140000 */
# define S U N 4 D _ B O O T B U S _ C P U I D 0 x f01 4 0 0 0 0
sun4d_init :
/* Need to patch call to handler_irq */
set p a t c h _ h a n d l e r _ i r q , % g 4
set s u n 4 d _ h a n d l e r _ i r q , % g 5
sethi % h i ( 0 x40 0 0 0 0 0 0 ) , % g 3 ! c a l l
sub % g 5 , % g 4 , % g 5
srl % g 5 , 2 , % g 5
or % g 5 , % g 3 , % g 5
st % g 5 , [ % g 4 ]
# ifdef C O N F I G _ S M P
/* Get our CPU id out of bootbus */
set S U N 4 D _ B O O T B U S _ C P U I D , % g 3
lduba [ % g 3 ] A S I _ M _ C T L , % g 3
and % g 3 , 0 x f8 , % g 3
srl % g 3 , 3 , % g 4
sta % g 4 , [ % g 0 ] A S I _ M _ V I K I N G _ T M P 1
sethi % h i ( b o o t _ c p u _ i d ) , % g 5
stb % g 4 , [ % g 5 + % l o ( b o o t _ c p u _ i d ) ]
# endif
/* Fall through to sun4m_init */
sun4m_init :
/ * Ok, t h e P R O M c o u l d h a v e d o n e f u n n y t h i n g s a n d a p p l e c i d e r c o u l d s t i l l
* be s i t t i n g i n t h e f a u l t s t a t u s / a d d r e s s r e g i s t e r s . R e a d t h e m a l l t o
* clear t h e m s o w e d o n ' t g e t m a g i c f a u l t s l a t e r o n .
* /
/* This sucks, apparently this makes Vikings call prom panic, will fix later */
2 :
rd % p s r , % o 1
2012-05-25 21:20:07 +00:00
srl % o 1 , P S R _ I M P L _ S H I F T , % o 1 ! G e t a t y p e o f t h e C P U
2005-04-16 15:20:36 -07:00
2012-05-25 21:20:07 +00:00
subcc % o 1 , P S R _ I M P L _ T I , % g 0 ! T I : V i k i n g o r M i c r o S P A R C
2012-05-11 11:35:15 +00:00
be c o n t i n u e _ b o o t
2005-04-16 15:20:36 -07:00
nop
set A C _ M _ S F S R , % o 0
lda [ % o 0 ] A S I _ M _ M M U R E G S , % g 0
set A C _ M _ S F A R , % o 0
lda [ % o 0 ] A S I _ M _ M M U R E G S , % g 0
/* Fujitsu MicroSPARC-II has no asynchronous flavors of FARs */
subcc % o 1 , 0 , % g 0
2012-05-11 11:35:15 +00:00
be c o n t i n u e _ b o o t
2005-04-16 15:20:36 -07:00
nop
set A C _ M _ A F S R , % o 0
lda [ % o 0 ] A S I _ M _ M M U R E G S , % g 0
set A C _ M _ A F A R , % o 0
lda [ % o 0 ] A S I _ M _ M M U R E G S , % g 0
nop
2012-05-11 11:35:15 +00:00
continue_boot :
2005-04-16 15:20:36 -07:00
/ * Aieee, n o w s e t P C a n d n P C , e n a b l e t r a p s , g i v e o u r s e l v e s a s t a c k a n d i t ' s
* show- t i m e !
* /
/ * Turn o n S u p e r v i s o r , E n a b l e F l o a t i n g , a n d a l l t h e P I L b i t s .
* Also p u t s u s i n r e g i s t e r w i n d o w z e r o w i t h t r a p s o f f .
* /
set ( P S R _ P S | P S R _ S | P S R _ P I L | P S R _ E F ) , % g 2
wr % g 2 , 0 x0 , % p s r
WRITE_ P A U S E
/* I want a kernel stack NOW! */
set i n i t _ t h r e a d _ u n i o n , % g 1
set ( T H R E A D _ S I Z E - S T A C K F R A M E _ S Z ) , % g 2
add % g 1 , % g 2 , % s p
mov 0 , % f p / * A n d f o r g o o d l u c k * /
/* Zero out our BSS section. */
set _ _ b s s _ s t a r t , % o 0 ! F i r s t a d d r e s s o f B S S
2008-12-27 00:35:12 -08:00
set _ e n d , % o 1 ! L a s t a d d r e s s o f B S S
2005-04-16 15:20:36 -07:00
add % o 0 , 0 x1 , % o 0
2012-05-25 21:20:05 +00:00
1 :
2005-04-16 15:20:36 -07:00
stb % g 0 , [ % o 0 ]
subcc % o 0 , % o 1 , % g 0
bl 1 b
add % o 0 , 0 x1 , % o 0
2011-04-21 04:20:23 +00:00
/ * If b o o t _ c p u _ i d h a s n o t b e e n s e t u p b y m a c h i n e s p e c i f i c
* init- c o d e a b o v e w e d e f a u l t i t t o z e r o .
* /
sethi % h i ( b o o t _ c p u _ i d ) , % g 2
ldub [ % g 2 + % l o ( b o o t _ c p u _ i d ) ] , % g 3
cmp % g 3 , 0 x f f
bne 1 f
nop
mov % g 0 , % g 3
stub % g 3 , [ % g 2 + % l o ( b o o t _ c p u _ i d ) ]
2012-05-19 21:40:50 -07:00
1 : sll % g 3 , 2 , % g 3
2011-04-21 04:20:23 +00:00
2005-04-16 15:20:36 -07:00
/ * Initialize t h e u w i n m a s k v a l u e f o r i n i t t a s k j u s t i n c a s e .
* But f i r s t m a k e c u r r e n t _ s e t [ b o o t _ c p u _ i d ] p o i n t t o s o m e t h i n g u s e f u l .
* /
set i n i t _ t h r e a d _ u n i o n , % g 6
set c u r r e n t _ s e t , % g 2
# ifdef C O N F I G _ S M P
st % g 6 , [ % g 2 ]
add % g 2 , % g 3 , % g 2
# endif
st % g 6 , [ % g 2 ]
st % g 0 , [ % g 6 + T I _ U W I N M A S K ]
/ * Compute N W I N D O W S a n d s t a s h i t a w a y . N o w u s e s % w i m t r i c k e x p l a i n e d
* in t h e V 8 m a n u a l . O k , t h i s m e t h o d s e e m s t o w o r k , S p a r c i s c o o l . . .
* No, i t d o e s n ' t w o r k , h a v e t o p l a y t h e s a v e / r e a d C W P / r e s t o r e t r i c k .
* /
wr % g 0 , 0 x0 , % w i m ! s o w e d o n o t g e t a t r a p
WRITE_ P A U S E
save
rd % p s r , % g 3
restore
and % g 3 , 0 x1 f , % g 3
add % g 3 , 0 x1 , % g 3
mov 2 , % g 1
wr % g 1 , 0 x0 , % w i m ! m a k e w i n d o w 1 i n v a l i d
WRITE_ P A U S E
cmp % g 3 , 0 x7
bne 2 f
nop
/ * Adjust o u r w i n d o w h a n d l i n g r o u t i n e s t o
* do t h i n g s c o r r e c t l y o n 7 w i n d o w S p a r c s .
* /
# define P A T C H _ I N S N ( s r c , d e s t ) \
set s r c , % g 5 ; \
set d e s t , % g 2 ; \
ld [ % g 5 ] , % g 4 ; \
st % g 4 , [ % g 2 ] ;
2012-05-25 21:20:05 +00:00
2005-04-16 15:20:36 -07:00
/* Patch for window spills... */
PATCH_ I N S N ( s p n w i n _ p a t c h1 _ 7 w i n , s p n w i n _ p a t c h1 )
PATCH_ I N S N ( s p n w i n _ p a t c h2 _ 7 w i n , s p n w i n _ p a t c h2 )
PATCH_ I N S N ( s p n w i n _ p a t c h3 _ 7 w i n , s p n w i n _ p a t c h3 )
/* Patch for window fills... */
PATCH_ I N S N ( f n w i n _ p a t c h1 _ 7 w i n , f n w i n _ p a t c h1 )
PATCH_ I N S N ( f n w i n _ p a t c h2 _ 7 w i n , f n w i n _ p a t c h2 )
/* Patch for trap entry setup... */
PATCH_ I N S N ( t s e t u p _ 7 w i n _ p a t c h1 , t s e t u p _ p a t c h1 )
PATCH_ I N S N ( t s e t u p _ 7 w i n _ p a t c h2 , t s e t u p _ p a t c h2 )
PATCH_ I N S N ( t s e t u p _ 7 w i n _ p a t c h3 , t s e t u p _ p a t c h3 )
PATCH_ I N S N ( t s e t u p _ 7 w i n _ p a t c h4 , t s e t u p _ p a t c h4 )
PATCH_ I N S N ( t s e t u p _ 7 w i n _ p a t c h5 , t s e t u p _ p a t c h5 )
PATCH_ I N S N ( t s e t u p _ 7 w i n _ p a t c h6 , t s e t u p _ p a t c h6 )
/* Patch for returning from traps... */
PATCH_ I N S N ( r t r a p _ 7 w i n _ p a t c h1 , r t r a p _ p a t c h1 )
PATCH_ I N S N ( r t r a p _ 7 w i n _ p a t c h2 , r t r a p _ p a t c h2 )
PATCH_ I N S N ( r t r a p _ 7 w i n _ p a t c h3 , r t r a p _ p a t c h3 )
PATCH_ I N S N ( r t r a p _ 7 w i n _ p a t c h4 , r t r a p _ p a t c h4 )
PATCH_ I N S N ( r t r a p _ 7 w i n _ p a t c h5 , r t r a p _ p a t c h5 )
/* Patch for killing user windows from the register file. */
PATCH_ I N S N ( k u w _ p a t c h1 _ 7 w i n , k u w _ p a t c h1 )
/ * Now p a t c h t h e k e r n e l w i n d o w f l u s h s e q u e n c e s .
* This s a v e s 2 t r a p s o n e v e r y s w i t c h a n d f o r k .
* /
set 0 x01 0 0 0 0 0 0 , % g 4
set f l u s h _ p a t c h _ o n e , % g 5
st % g 4 , [ % g 5 + 0 x18 ]
st % g 4 , [ % g 5 + 0 x1 c ]
set f l u s h _ p a t c h _ t w o , % g 5
st % g 4 , [ % g 5 + 0 x18 ]
st % g 4 , [ % g 5 + 0 x1 c ]
set f l u s h _ p a t c h _ t h r e e , % g 5
st % g 4 , [ % g 5 + 0 x18 ]
st % g 4 , [ % g 5 + 0 x1 c ]
set f l u s h _ p a t c h _ f o u r , % g 5
st % g 4 , [ % g 5 + 0 x18 ]
st % g 4 , [ % g 5 + 0 x1 c ]
set f l u s h _ p a t c h _ e x c e p t i o n , % g 5
st % g 4 , [ % g 5 + 0 x18 ]
st % g 4 , [ % g 5 + 0 x1 c ]
set f l u s h _ p a t c h _ s w i t c h , % g 5
st % g 4 , [ % g 5 + 0 x18 ]
st % g 4 , [ % g 5 + 0 x1 c ]
2012-05-25 21:20:05 +00:00
2 :
2005-04-16 15:20:36 -07:00
sethi % h i ( n w i n d o w s ) , % g 4
st % g 3 , [ % g 4 + % l o ( n w i n d o w s ) ] ! s t o r e f i n a l v a l u e
sub % g 3 , 0 x1 , % g 3
sethi % h i ( n w i n d o w s m 1 ) , % g 4
st % g 3 , [ % g 4 + % l o ( n w i n d o w s m 1 ) ]
/* Here we go, start using Linux's trap table... */
set t r a p b a s e , % g 3
wr % g 3 , 0 x0 , % t b r
WRITE_ P A U S E
/* Finally, turn on traps so that we can call c-code. */
rd % p s r , % g 3
wr % g 3 , 0 x0 , % p s r
WRITE_ P A U S E
wr % g 3 , P S R _ E T , % p s r
WRITE_ P A U S E
2012-05-25 21:20:08 +00:00
/* Call sparc32_start_kernel(struct linux_romvec *rp) */
2005-04-16 15:20:36 -07:00
sethi % h i ( p r o m _ v e c t o r _ p ) , % g 5
ld [ % g 5 + % l o ( p r o m _ v e c t o r _ p ) ] , % o 0
2012-05-25 21:20:08 +00:00
call s p a r c32 _ s t a r t _ k e r n e l
2005-04-16 15:20:36 -07:00
nop
2012-05-25 21:20:05 +00:00
2005-04-16 15:20:36 -07:00
/* We should not get here. */
call h a l t _ m e
nop
2008-08-31 20:59:37 -07:00
2005-04-16 15:20:36 -07:00
no_sun4e_here :
ld [ % g 7 + 0 x68 ] , % o 1
set s u n 4 e _ n o t s u p , % o 0
call % o 1
nop
b h a l t _ m e
nop
_ _ INITDATA
sun4u_1 :
.asciz " finddevice"
.align 4
sun4u_2 :
.asciz " / chosen"
.align 4
sun4u_3 :
.asciz " getprop"
.align 4
sun4u_4 :
.asciz " stdout"
.align 4
sun4u_5 :
.asciz " write"
.align 4
sun4u_6 :
2012-05-25 21:20:05 +00:00
.asciz " \ n\ r O n s u n 4 u y o u h a v e t o u s e s p a r c64 k e r n e l \ n \ r a n d n o t a s p a r c32 v e r s i o n \ n \ r \ n \ r "
2005-04-16 15:20:36 -07:00
sun4u_6e :
.align 4
sun4u_7 :
.asciz " exit"
.align 8
sun4u_a1 :
.word 0 , sun4 u _ 1 , 0 , 1 , 0 , 1 , 0 , s u n 4 u _ 2 , 0
sun4u_r1 :
.word 0
sun4u_a2 :
.word 0 , sun4 u _ 3 , 0 , 4 , 0 , 1 , 0
sun4u_i2 :
.word 0 , 0 , sun4 u _ 4 , 0 , s u n 4 u _ 1 , 0 , 8 , 0
sun4u_r2 :
.word 0
sun4u_a3 :
.word 0 , sun4 u _ 5 , 0 , 3 , 0 , 1 , 0
sun4u_i3 :
.word 0 , 0 , sun4 u _ 6 , 0 , s u n 4 u _ 6 e - s u n 4 u _ 6 - 1 , 0
sun4u_r3 :
.word 0
sun4u_a4 :
.word 0 , sun4 u _ 7 , 0 , 0 , 0 , 0
sun4u_r4 :
_ _ INIT
no_sun4u_here :
set s u n 4 u _ a1 , % o 0
set c u r r e n t _ p c , % l 2
cmp % l 2 , % g 3
be 1 f
mov % o 4 , % l 0
sub % g 3 , % l 2 , % l 6
add % o 0 , % l 6 , % o 0
mov % o 0 , % l 4
mov s u n 4 u _ r4 - s u n 4 u _ a1 , % l 3
ld [ % l 4 ] , % l 5
2 :
add % l 4 , 4 , % l 4
cmp % l 5 , % l 2
add % l 5 , % l 6 , % l 5
bgeu,a 3 f
st % l 5 , [ % l 4 - 4 ]
3 :
subcc % l 3 , 4 , % l 3
bne 2 b
ld [ % l 4 ] , % l 5
1 :
call % l 0
mov % o 0 , % l 1
ld [ % l 1 + ( s u n 4 u _ r1 - s u n 4 u _ a1 ) ] , % o 1
add % l 1 , ( s u n 4 u _ a2 - s u n 4 u _ a1 ) , % o 0
call % l 0
st % o 1 , [ % o 0 + ( s u n 4 u _ i 2 - s u n 4 u _ a2 ) ]
ld [ % l 1 + ( s u n 4 u _ 1 - s u n 4 u _ a1 ) ] , % o 1
add % l 1 , ( s u n 4 u _ a3 - s u n 4 u _ a1 ) , % o 0
call % l 0
st % o 1 , [ % o 0 + ( s u n 4 u _ i 3 - s u n 4 u _ a3 ) ]
call % l 0
add % l 1 , ( s u n 4 u _ a4 - s u n 4 u _ a1 ) , % o 0
/* Not reached */
halt_me :
ld [ % g 7 + 0 x74 ] , % o 0
call % o 0 ! G e t u s o u t o f h e r e . . .
nop ! A p p a r e n t l y S o l a r i s i s b e t t e r .
/* Ok, now we continue in the .data/.text sections */
.data
.align 4
/ *
* Fill u p t h e p r o m v e c t o r , n o t e i n p a r t i c u l a r t h e k i n d f i r s t e l e m e n t ,
* no j o k e . I d o n ' t n e e d a l l o f t h e m i n h e r e a s t h e e n t i r e p r o m v e c t o r
* gets i n i t i a l i z e d i n c - c o d e s o a l l r o u t i n e s c a n u s e i t .
* /
prom_vector_p :
.word 0
/ * We c a l c u l a t e t h e f o l l o w i n g a t b o o t t i m e , w i n d o w f i l l s / s p i l l s a n d t r a p e n t r y
* code u s e s t h e s e t o k e e p t r a c k o f t h e r e g i s t e r w i n d o w s .
* /
.align 4
.globl nwindows
.globl nwindowsm1
nwindows :
.word 8
nwindowsm1 :
.word 7
/* Boot time debugger vector value. We need this later on. */
.align 4
.globl linux_dbvec
linux_dbvec :
.word 0
.word 0
.align 8
.globl lvl14_save
lvl14_save :
.word 0
.word 0
.word 0
.word 0
.word t_irq14
.section " .fixup " , # alloc,#e x e c i n s t r
.globl __ret_efault
__ret_efault :
ret
restore % g 0 , - E F A U L T , % o 0