2018-12-28 11:32:24 +03:00
/ * SPDX- L i c e n s e - I d e n t i f i e r : G P L - 2 . 0
*
2006-01-17 09:14:10 +03:00
* relocate_ k e r n e l . S - p u t t h e k e r n e l i m a g e i n p l a c e t o b o o t
* 2 0 0 5 .9 .17 kogiidena@eggplant.ddo.jp
*
* LANDISK/ s h4 i s s u p p o r t e d . M a y b e , S H a r c h t e c t u r e w o r k s w e l l .
*
2009-03-18 11:51:29 +03:00
* 2 0 0 9 - 0 3 - 1 8 Magnus D a m m - A d d e d K e x e c J u m p s u p p o r t
2006-01-17 09:14:10 +03:00
* /
# include < l i n u x / l i n k a g e . h >
2006-11-27 06:06:26 +03:00
# include < a s m / a d d r s p a c e . h >
# include < a s m / p a g e . h >
2006-01-17 09:14:10 +03:00
.globl relocate_new_kernel
relocate_new_kernel :
/* r4 = indirection_page */
/* r5 = reboot_code_buffer */
/* r6 = start_address */
2009-03-18 11:51:29 +03:00
mov. l 1 0 f , r0 / * P A G E _ S I Z E * /
add r5 , r0 / * s e t u p n e w s t a c k a t e n d o f c o n t r o l p a g e * /
/* save r15->r8 to new stack */
mov. l r15 , @-r0
mov r0 , r15
mov. l r14 , @-r15
mov. l r13 , @-r15
mov. l r12 , @-r15
mov. l r11 , @-r15
mov. l r10 , @-r15
mov. l r9 , @-r15
mov. l r8 , @-r15
/* save other random registers */
sts. l m a c l , @-r15
sts. l m a c h , @-r15
stc. l g b r , @-r15
stc. l s s r , @-r15
stc. l s r , @-r15
sts. l p r , @-r15
stc. l s p c , @-r15
/* switch to bank1 and save r7->r0 */
mov. l 1 2 f , r9
stc s r , r8
or r9 , r8
ldc r8 , s r
mov. l r7 , @-r15
mov. l r6 , @-r15
mov. l r5 , @-r15
mov. l r4 , @-r15
mov. l r3 , @-r15
mov. l r2 , @-r15
mov. l r1 , @-r15
mov. l r0 , @-r15
/* switch to bank0 and save r7->r0 */
mov. l 1 2 f , r9
not r9 , r9
stc s r , r8
and r9 , r8
ldc r8 , s r
mov. l r7 , @-r15
mov. l r6 , @-r15
mov. l r5 , @-r15
mov. l r4 , @-r15
mov. l r3 , @-r15
mov. l r2 , @-r15
mov. l r1 , @-r15
mov. l r0 , @-r15
mov. l r4 , @-r15 /* save indirection page again */
bsr s w a p _ p a g e s / * s w a p p a g e s b e f o r e j u m p i n g t o n e w k e r n e l * /
nop
mova 1 1 f , r0
mov. l r15 , @r0 /* save pointer to stack */
jsr @r6 /* hand over control to new kernel */
nop
mov. l 1 1 f , r15 / * g e t p o i n t e r t o s t a c k * /
mov. l @r15+, r4 /* restore r4 to get indirection page */
2006-01-17 09:14:10 +03:00
2009-03-18 11:51:29 +03:00
bsr s w a p _ p a g e s / * s w a p p a g e s b a c k t o p r e v i o u s s t a t e * /
nop
2006-01-17 09:14:10 +03:00
2009-03-18 11:51:29 +03:00
/* make sure bank0 is active and restore r0->r7 */
mov. l 1 2 f , r9
not r9 , r9
stc s r , r8
and r9 , r8
ldc r8 , s r
mov. l @r15+, r0
mov. l @r15+, r1
mov. l @r15+, r2
mov. l @r15+, r3
mov. l @r15+, r4
mov. l @r15+, r5
mov. l @r15+, r6
mov. l @r15+, r7
/* switch to bank1 and restore r0->r7 */
mov. l 1 2 f , r9
stc s r , r8
or r9 , r8
ldc r8 , s r
mov. l @r15+, r0
mov. l @r15+, r1
mov. l @r15+, r2
mov. l @r15+, r3
mov. l @r15+, r4
mov. l @r15+, r5
mov. l @r15+, r6
mov. l @r15+, r7
/* switch back to bank0 */
mov. l 1 2 f , r9
not r9 , r9
stc s r , r8
and r9 , r8
ldc r8 , s r
/* restore other random registers */
ldc. l @r15+, spc
lds. l @r15+, pr
ldc. l @r15+, sr
ldc. l @r15+, ssr
ldc. l @r15+, gbr
lds. l @r15+, mach
lds. l @r15+, macl
/* restore r8->r15 */
mov. l @r15+, r8
mov. l @r15+, r9
mov. l @r15+, r10
mov. l @r15+, r11
mov. l @r15+, r12
mov. l @r15+, r13
mov. l @r15+, r14
mov. l @r15+, r15
rts
nop
swap_pages :
2006-01-17 09:14:10 +03:00
bra 1 f
2009-03-18 11:51:29 +03:00
mov r4 ,r0 / * c m d = i n d i r e c t i o n _ p a g e * /
2006-01-17 09:14:10 +03:00
0 :
mov. l @r4+,r0 /* cmd = *ind++ */
2009-03-18 11:49:45 +03:00
1 : /* addr = cmd & 0xfffffff0 */
2006-01-17 09:14:10 +03:00
mov r0 ,r2
mov #- 16 ,r1
and r1 ,r2
/* if(cmd & IND_DESTINATION) dst = addr */
tst #1 ,r0
bt 2 f
bra 0 b
2009-03-18 11:51:29 +03:00
mov r2 ,r5
2006-01-17 09:14:10 +03:00
2 : /* else if(cmd & IND_INDIRECTION) ind = addr */
tst #2 ,r0
bt 3 f
bra 0 b
2009-03-18 11:51:29 +03:00
mov r2 ,r4
2006-01-17 09:14:10 +03:00
2009-03-18 11:51:29 +03:00
3 : /* else if(cmd & IND_DONE) return */
2006-01-17 09:14:10 +03:00
tst #4 ,r0
bt 4 f
2009-03-18 11:51:29 +03:00
rts
nop
2006-01-17 09:14:10 +03:00
4 : /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
tst #8 ,r0
bt 0 b
2009-03-18 11:51:29 +03:00
mov. l 1 0 f ,r3 / * P A G E _ S I Z E * /
2006-01-17 09:14:10 +03:00
shlr2 r3
shlr2 r3
5 :
dt r3
2009-03-18 11:51:29 +03:00
/ * regular k e x e c j u s t o v e r w r i t e s t h e d e s t i n a t i o n p a g e
* with t h e c o n t e n t s o f t h e s o u r c e p a g e .
* for t h e k e x e c j u m p c a s e w e n e e d t o s w a p t h e c o n t e n t s
* of t h e p a g e s .
* to k e e p i t s i m p l e s w a p t h e c o n t e n t s f o r b o t h c a s e s .
* /
mov. l @(0, r2), r8
mov. l @(0, r5), r1
mov. l r8 , @(0, r5)
mov. l r1 , @(0, r2)
mov. l @(4, r2), r8
mov. l @(4, r5), r1
mov. l r8 , @(4, r5)
mov. l r1 , @(4, r2)
mov. l @(8, r2), r8
mov. l @(8, r5), r1
mov. l r8 , @(8, r5)
mov. l r1 , @(8, r2)
mov. l @(12, r2), r8
mov. l @(12, r5), r1
mov. l r8 , @(12, r5)
mov. l r1 , @(12, r2)
add #16 ,r5
add #16 ,r2
2006-01-17 09:14:10 +03:00
bf 5 b
bra 0 b
2009-03-18 11:51:29 +03:00
nop
2006-01-17 09:14:10 +03:00
.align 2
10 :
.long PAGE_SIZE
2009-03-18 11:51:29 +03:00
11 :
.long 0
12 :
.long 0x20000000 ! RB=1
2006-01-17 09:14:10 +03:00
relocate_new_kernel_end :
.globl relocate_new_kernel_size
relocate_new_kernel_size :
.long relocate_new_kernel_end - relocate_ n e w _ k e r n e l