2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / m 3 2 r / k e r n e l / h e a d . S
*
* M3 2 R s t a r t u p c o d e .
*
* Copyright ( c ) 2 0 0 1 , 2 0 0 2 H i r o y u k i K o n d o , H i r o k a z u T a k a t a ,
* Hitoshi Y a m a m o t o
* /
# include < l i n u x / i n i t . h >
_ _ INIT
_ _ INITDATA
.text
# include < l i n u x / l i n k a g e . h >
# include < a s m / s e g m e n t . h >
# include < a s m / p a g e . h >
# include < a s m / p g t a b l e . h >
# include < a s m / a s s e m b l e r . h >
# include < a s m / m 3 2 r . h >
# include < a s m / m m u _ c o n t e x t . h >
/ *
* References t o m e m b e r s o f t h e b o o t _ c p u _ d a t a s t r u c t u r e .
* /
2009-04-25 22:11:02 -04:00
_ _ HEAD
2005-04-16 15:20:36 -07:00
.global start_kernel
.global __bss_start
.global _end
ENTRY( s t e x t )
ENTRY( _ s t e x t )
/* Setup up the stack pointer */
LDIMM ( r0 , s p i _ s t a c k _ t o p )
LDIMM ( r1 , s p u _ s t a c k _ t o p )
mvtc r0 , s p i
mvtc r1 , s p u
/* Initilalize PSW */
ldi r0 , #0x0000 / * u s e S P I , d i s a b l e E I * /
mvtc r0 , p s w
/* Set up the stack pointer */
LDIMM ( r0 , s t a c k _ s t a r t )
ld r0 , @r0
mvtc r0 , s p i
/ *
* Clear B S S f i r s t s o t h a t t h e r e a r e n o s u r p r i s e s . . .
* /
# ifdef C O N F I G _ I S A _ D U A L _ I S S U E
LDIMM ( r2 , _ _ b s s _ s t a r t )
LDIMM ( r3 , _ e n d )
sub r3 , r2 ; BSS size in bytes
; R4 = BSS size in longwords (rounded down)
mv r4 , r3 | | l d i r1 , #0
srli r4 , #4 | | a d d i r2 , #- 4
beqz r4 , . L e n d l o o p1
.Lloop1 :
# ifndef C O N F I G _ C H I P _ M 3 2 3 1 0
; Touch memory for the no-write-allocating cache.
ld r0 , @(4,r2)
# endif
st r1 , @+r2 || addi r4, #-1
st r1 , @+r2
st r1 , @+r2
st r1 , @+r2 || cmpeq r1, r4 ; R4 = 0?
bnc . L l o o p1
.Lendloop1 :
and3 r4 , r3 , #15
addi r2 , #4
beqz r4 , . L e n d l o o p2
.Lloop2 :
stb r1 , @r2 || addi r4, #-1
addi r2 , #1
bnez r4 , . L l o o p2
.Lendloop2 :
# else / * n o t C O N F I G _ I S A _ D U A L _ I S S U E * /
LDIMM ( r2 , _ _ b s s _ s t a r t )
LDIMM ( r3 , _ e n d )
sub r3 , r2 ; BSS size in bytes
mv r4 , r3
srli r4 , #2 ; R4 = BSS size in longwords (rounded down)
ldi r1 , #0 ; clear R1 for longwords store
addi r2 , #- 4 ; account for pre-inc store
beqz r4 , . L e n d l o o p1 ; any more to go?
.Lloop1 :
st r1 , @+r2 ; yep, zero out another longword
addi r4 , #- 1 ; decrement count
bnez r4 , . L l o o p1 ; go do some more
.Lendloop1 :
and3 r4 , r3 , #3 ; get no. of remaining BSS bytes to clear
addi r2 , #4 ; account for pre-inc store
beqz r4 , . L e n d l o o p2 ; any more to go?
.Lloop2 :
stb r1 , @r2 ; yep, zero out another byte
addi r2 , #1 ; bump address
addi r4 , #- 1 ; decrement count
bnez r4 , . L l o o p2 ; go do some more
.Lendloop2 :
# endif / * n o t C O N F I G _ I S A _ D U A L _ I S S U E * /
# if 0 / * M 3 2 R _ F I X M E * /
/ *
* Copy d a t a s e g m e n t f r o m R O M t o R A M .
* /
.global ROM_ D , T O P _ D A T A , E N D _ D A T A
LDIMM ( r1 , R O M _ D )
LDIMM ( r2 , T O P _ D A T A )
LDIMM ( r3 , E N D _ D A T A )
addi r2 , #- 4
addi r3 , #- 4
loop1 :
ld r0 , @r1+
st r0 , @+r2
cmp r2 , r3
bc l o o p1
# endif / * 0 * /
/* Jump to kernel */
LDIMM ( r2 , s t a r t _ k e r n e l )
jl r2
.fillinsn
1 :
bra 1 b ; main should never return here, but
; just in case, we know what happens.
# ifdef C O N F I G _ S M P
/ *
* AP s t a r t u p r o u t i n e
* /
.global eit_vector
ENTRY( s t a r t u p _ A P )
;; setup EVB
LDIMM ( r4 , e i t _ v e c t o r )
mvtc r4 , c r5
;; enable MMU
LDIMM ( r2 , i n i t _ t l b )
jl r2
seth r4 , #h i g h ( M A T M )
or3 r4 , r4 , #l o w ( M A T M )
ldi r5 , #0x01
st r5 , @r4 ; Set MATM Reg(T bit ON)
ld r6 , @r4 ; MATM Check
LDIMM ( r5 , 1 f )
jmp r5 ; enable MMU
nop
.fillinsn
1 :
;; ISN check
ld r6 , @r4 ; MATM Check
seth r4 , #h i g h ( M 32 R _ I C U _ I S T S _ A D D R )
or3 r4 , r4 , #l o w ( M 32 R _ I C U _ I S T S _ A D D R )
ld r5 , @r4 ; Read ISTSi reg.
mv r6 , r5
slli r5 , #13 ; PIML check
srli r5 , #13 ;
seth r4 , #h i g h ( M 32 R _ I C U _ I M A S K _ A D D R )
or3 r4 , r4 , #l o w ( M 32 R _ I C U _ I M A S K _ A D D R )
st r5 , @r4 ; Write IMASKi reg.
slli r6 , #4 ; ISN check
srli r6 , #26 ;
seth r4 , #h i g h ( M 32 R _ I R Q _ I P I 5 )
or3 r4 , r4 , #l o w ( M 32 R _ I R Q _ I P I 5 )
bne r4 , r6 , 2 f ; if (ISN != CPU_BOOT_IPI) goto sleep;
;; check cpu_bootout_map and set cpu_bootin_map
LDIMM ( r4 , c p u _ b o o t o u t _ m a p )
ld r4 , @r4
seth r5 , #h i g h ( M 32 R _ C P U I D _ P O R T L )
or3 r5 , r5 , #l o w ( M 32 R _ C P U I D _ P O R T L )
ld r5 , @r5
ldi r6 , #1
sll r6 , r5
and r4 , r6
beqz r4 , 2 f
LDIMM ( r4 , c p u _ b o o t i n _ m a p )
ld r5 , @r4
or r5 , r6
st r6 , @r4
;; clear PSW
ldi r4 , #0
mvtc r4 , p s w
;; setup SPI
LDIMM ( r4 , s t a c k _ s t a r t )
ld r4 , @r4
mvtc r4 , s p i
;; setup BPC (start_secondary)
LDIMM ( r4 , s t a r t _ s e c o n d a r y )
mvtc r4 , b p c
rte ; goto startup_secondary
nop
nop
.fillinsn
2 :
;; disable MMU
seth r4 , #h i g h ( M A T M )
or3 r4 , r4 , #l o w ( M A T M )
ldi r5 , #0
st r5 , @r4 ; Set MATM Reg(T bit OFF)
ld r6 , @r4 ; MATM Check
LDIMM ( r4 , 3 f )
seth r5 , #h i g h ( _ _ P A G E _ O F F S E T )
or3 r5 , r5 , #l o w ( _ _ P A G E _ O F F S E T )
not r5 , r5
and r4 , r5
jmp r4 ; disable MMU
nop
.fillinsn
3 :
;; SLEEP and wait IPI
LDIMM ( r4 , A P _ l o o p )
seth r5 , #h i g h ( _ _ P A G E _ O F F S E T )
or3 r5 , r5 , #l o w ( _ _ P A G E _ O F F S E T )
not r5 , r5
and r4 , r5
jmp r4
nop
nop
# endif / * C O N F I G _ S M P * /
2008-11-22 17:35:54 +00:00
.text
2005-04-16 15:20:36 -07:00
ENTRY( s t a c k _ s t a r t )
.long init_ t h r e a d _ u n i o n + 8 1 9 2
.long __KERNEL_DS
/ *
* This i s i n i t i a l i z e d t o c r e a t e a i d e n t i t y - m a p p i n g a t 0 - 4 M ( f o r b o o t u p
* purposes) a n d a n o t h e r m a p p i n g o f t h e 0 - 4 M a r e a a t v i r t u a l a d d r e s s
* PAGE_ O F F S E T .
* /
.text
# define M O U N T _ R O O T _ R D O N L Y 1
# define R A M D I S K _ F L A G S 0 ; 1024KB
# define O R I G _ R O O T _ D E V 0 x01 0 0 ; /dev/ram0 (major:01, minor:00)
# define L O A D E R _ T Y P E 1 ; (??? - non-zero value seems
; to be needed to boot from initrd)
# define C O M M A N D _ L I N E " "
.section .empty_zero_page , " aw"
ENTRY( e m p t y _ z e r o _ p a g e )
.long MOUNT_ROOT_RDONLY /* offset: +0x00 */
.long RAMDISK_FLAGS
.long ORIG_ROOT_DEV
.long LOADER_TYPE
.long 0 /* INITRD_START */ /* +0x10 */
.long 0 /* INITRD_SIZE */
.long 0 /* CPU_CLOCK */
.long 0 /* BUS_CLOCK */
.long 0 /* TIMER_DIVIDE */ /* +0x20 */
.balign 2 5 6 , 0
.asciz COMMAND_LINE
.byte 0
.balign 4 0 9 6 , 0 , 4 0 9 6
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Stack a r e a
* /
2009-09-18 16:32:48 -04:00
.section .init .data , " aw"
2005-04-16 15:20:36 -07:00
ALIGN
.global spi_stack_top
.zero 1024
spi_stack_top :
2009-09-18 16:32:48 -04:00
.section .init .data , " aw"
2005-04-16 15:20:36 -07:00
ALIGN
.global spu_stack_top
.zero 1024
spu_stack_top :
.end