2021-04-19 03:55:36 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
/ *
* Copyright ( C ) 2 0 1 9 F O R T H - I C S / C A R V
* Nick K o s s i f i d i s < m i c k @ics.forth.gr>
* /
# include < a s m / a s m . h > / * F o r R I S C V _ * a n d R E G _ * m a c r o s * /
# include < a s m / c s r . h > / * F o r C S R _ * m a c r o s * /
# include < a s m / p a g e . h > / * F o r P A G E _ S I Z E * /
# include < l i n u x / l i n k a g e . h > / * F o r S Y M _ * m a c r o s * /
.section " .rodata "
SYM_ C O D E _ S T A R T ( r i s c v _ k e x e c _ r e l o c a t e )
/ *
* s0 : Pointer t o t h e c u r r e n t e n t r y
* s1 : ( const) P h y s a d d r e s s t o j u m p t o a f t e r r e l o c a t i o n
* s2 : ( const) P h y s a d d r e s s o f t h e F D T i m a g e
* s3 : ( const) T h e h a r t i d o f t h e c u r r e n t h a r t
* s4 : Pointer t o t h e d e s t i n a t i o n a d d r e s s f o r t h e r e l o c a t i o n
* s5 : ( const) N u m b e r o f w o r d s p e r p a g e
* s6 : ( const) 1 , u s e d f o r s u b t r a c t i o n
2021-06-17 16:53:07 +03:00
* s7 : ( const) k e r n e l _ m a p . v a _ p a _ o f f s e t , u s e d w h e n s w i t c h i n g M M U o f f
2021-04-19 03:55:36 +03:00
* s8 : ( const) P h y s i c a l a d d r e s s o f t h e m a i n l o o p
* s9 : ( debug) i n d i r e c t i o n p a g e c o u n t e r
* s10 : ( debug) e n t r y c o u n t e r
* s11 : ( debug) c o p i e d w o r d s c o u n t e r
* /
mv s0 , a0
mv s1 , a1
mv s2 , a2
mv s3 , a3
mv s4 , z e r o
li s5 , ( P A G E _ S I Z E / R I S C V _ S Z P T R )
li s6 , 1
mv s7 , a4
mv s8 , z e r o
mv s9 , z e r o
mv s10 , z e r o
mv s11 , z e r o
/* Disable / cleanup interrupts */
csrw C S R _ S I E , z e r o
csrw C S R _ S I P , z e r o
/ *
* When w e s w i t c h S A T P . M O D E t o " B a r e " w e ' l l o n l y
* play w i t h p h y s i c a l a d d r e s s e s . H o w e v e r t h e f i r s t t i m e
* we t r y t o j u m p s o m e w h e r e , t h e o f f s e t o n t h e j u m p
* will b e r e l a t i v e t o p c w h i c h w i l l s t i l l b e o n V A . T o
* deal w i t h t h i s w e s e t s t v e c t o t h e p h y s i c a l a d d r e s s a t
* the s t a r t o f t h e l o o p b e l o w s o t h a t w e j u m p t h e r e i n
* any c a s e .
* /
la s8 , 1 f
sub s8 , s8 , s7
csrw C S R _ S T V E C , s8
/* Process entries in a loop */
.align 2
1 :
addi s10 , s10 , 1
REG_ L t 0 , 0 ( s0 ) / * t 0 = * i m a g e - > e n t r y * /
addi s0 , s0 , R I S C V _ S Z P T R / * i m a g e - > e n t r y + + * /
/* IND_DESTINATION entry ? -> save destination address */
andi t 1 , t 0 , 0 x1
beqz t 1 , 2 f
andi s4 , t 0 , ~ 0 x1
j 1 b
2 :
/* IND_INDIRECTION entry ? -> update next entry ptr (PA) */
andi t 1 , t 0 , 0 x2
beqz t 1 , 2 f
andi s0 , t 0 , ~ 0 x2
addi s9 , s9 , 1
csrw C S R _ S A T P , z e r o
jalr z e r o , s8 , 0
2 :
/* IND_DONE entry ? -> jump to done label */
andi t 1 , t 0 , 0 x4
beqz t 1 , 2 f
j 4 f
2 :
/ *
* IND_ S O U R C E e n t r y ? - > c o p y p a g e w o r d b y w o r d t o t h e
* destination a d d r e s s w e g o t f r o m I N D _ D E S T I N A T I O N
* /
andi t 1 , t 0 , 0 x8
beqz t 1 , 1 b / * U n k n o w n e n t r y t y p e , i g n o r e i t * /
andi t 0 , t 0 , ~ 0 x8
mv t 3 , s5 / * i = n u m w o r d s p e r p a g e * /
3 : /* copy loop */
REG_ L t 1 , ( t 0 ) / * t 1 = * s r c _ p t r * /
REG_ S t 1 , ( s4 ) / * * d s t _ p t r = * s r c _ p t r * /
addi t 0 , t 0 , R I S C V _ S Z P T R / * s t c _ p t r + + * /
addi s4 , s4 , R I S C V _ S Z P T R / * d s t _ p t r + + * /
sub t 3 , t 3 , s6 / * i - - * /
addi s11 , s11 , 1 / * c + + * /
beqz t 3 , 1 b / * c o p y d o n e ? * /
j 3 b
4 :
/* Pass the arguments to the next kernel / Cleanup*/
mv a0 , s3
mv a1 , s2
mv a2 , s1
/* Cleanup */
mv a3 , z e r o
mv a4 , z e r o
mv a5 , z e r o
mv a6 , z e r o
mv a7 , z e r o
mv s0 , z e r o
mv s1 , z e r o
mv s2 , z e r o
mv s3 , z e r o
mv s4 , z e r o
mv s5 , z e r o
mv s6 , z e r o
mv s7 , z e r o
mv s8 , z e r o
mv s9 , z e r o
mv s10 , z e r o
mv s11 , z e r o
mv t 0 , z e r o
mv t 1 , z e r o
mv t 2 , z e r o
mv t 3 , z e r o
mv t 4 , z e r o
mv t 5 , z e r o
mv t 6 , z e r o
csrw C S R _ S E P C , z e r o
csrw C S R _ S C A U S E , z e r o
csrw C S R _ S S C R A T C H , z e r o
/ *
* Make s u r e t h e r e l o c a t e d c o d e i s v i s i b l e
* and j u m p t o t h e n e w k e r n e l
* /
fence. i
jalr z e r o , a2 , 0
SYM_ C O D E _ E N D ( r i s c v _ k e x e c _ r e l o c a t e )
riscv_kexec_relocate_end :
2021-04-19 03:55:38 +03:00
/* Used for jumping to crashkernel */
.section " .text "
SYM_ C O D E _ S T A R T ( r i s c v _ k e x e c _ n o r e l o c a t e )
/ *
* s0 : ( const) P h y s a d d r e s s t o j u m p t o
* s1 : ( const) P h y s a d d r e s s o f t h e F D T i m a g e
* s2 : ( const) T h e h a r t i d o f t h e c u r r e n t h a r t
* /
mv s0 , a1
mv s1 , a2
mv s2 , a3
/* Disable / cleanup interrupts */
csrw C S R _ S I E , z e r o
csrw C S R _ S I P , z e r o
/* Pass the arguments to the next kernel / Cleanup*/
mv a0 , s2
mv a1 , s1
mv a2 , s0
/* Cleanup */
mv a3 , z e r o
mv a4 , z e r o
mv a5 , z e r o
mv a6 , z e r o
mv a7 , z e r o
mv s0 , z e r o
mv s1 , z e r o
mv s2 , z e r o
mv s3 , z e r o
mv s4 , z e r o
mv s5 , z e r o
mv s6 , z e r o
mv s7 , z e r o
mv s8 , z e r o
mv s9 , z e r o
mv s10 , z e r o
mv s11 , z e r o
mv t 0 , z e r o
mv t 1 , z e r o
mv t 2 , z e r o
mv t 3 , z e r o
mv t 4 , z e r o
mv t 5 , z e r o
mv t 6 , z e r o
csrw C S R _ S E P C , z e r o
csrw C S R _ S C A U S E , z e r o
csrw C S R _ S S C R A T C H , z e r o
2021-11-26 21:04:09 +03:00
/ *
* Switch t o p h y s i c a l a d d r e s s i n g
* This w i l l a l s o t r i g g e r a j u m p t o C S R _ S T V E C
* which i n t h i s c a s e i s t h e a d d r e s s o f t h e n e w
* kernel.
* /
csrw C S R _ S T V E C , a2
csrw C S R _ S A T P , z e r o
2021-04-19 03:55:38 +03:00
SYM_ C O D E _ E N D ( r i s c v _ k e x e c _ n o r e l o c a t e )
.section " .rodata "
2021-04-19 03:55:36 +03:00
SYM_ D A T A ( r i s c v _ k e x e c _ r e l o c a t e _ s i z e ,
.long riscv_kexec_relocate_end - riscv_ k e x e c _ r e l o c a t e )