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 .
*
* This s o u r c e c o d e i s l i c e n s e d u n d e r t h e G N U G e n e r a l P u b l i c L i c e n s e ,
* Version 2 . S e e t h e f i l e C O P Y I N G f o r m o r e d e t a i l s .
* /
# 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 */
/* r7 = vbr_reg */
2006-11-27 06:06:26 +03:00
mov. l 1 0 f ,r8 / * P A G E _ S I Z E * /
mov. l 1 1 f ,r9 / * P 2 S E G * /
2006-01-17 09:14:10 +03:00
/* stack setting */
add r8 ,r5
mov r5 ,r15
bra 1 f
mov r4 ,r0 / * c m d = i n d i r e c t i o n _ p a g e * /
0 :
mov. l @r4+,r0 /* cmd = *ind++ */
2006-11-27 06:06:26 +03:00
1 : /* addr = (cmd | P2SEG) & 0xfffffff0 */
2006-01-17 09:14:10 +03:00
mov r0 ,r2
or r9 ,r2
mov #- 16 ,r1
and r1 ,r2
/* if(cmd & IND_DESTINATION) dst = addr */
tst #1 ,r0
bt 2 f
bra 0 b
mov r2 ,r5
2 : /* else if(cmd & IND_INDIRECTION) ind = addr */
tst #2 ,r0
bt 3 f
bra 0 b
mov r2 ,r4
3 : /* else if(cmd & IND_DONE) goto 6 */
tst #4 ,r0
bt 4 f
bra 6 f
nop
4 : /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
tst #8 ,r0
bt 0 b
mov r8 ,r3
shlr2 r3
shlr2 r3
5 :
dt r3
mov. l @r2+,r1 /* 16n+0 */
mov. l r1 ,@r5
add #4 ,r5
mov. l @r2+,r1 /* 16n+4 */
mov. l r1 ,@r5
add #4 ,r5
mov. l @r2+,r1 /* 16n+8 */
mov. l r1 ,@r5
add #4 ,r5
mov. l @r2+,r1 /* 16n+12 */
mov. l r1 ,@r5
add #4 ,r5
bf 5 b
bra 0 b
nop
6 :
# ifdef C O N F I G _ S H _ S T A N D A R D _ B I O S
ldc r7 , v b r
# endif
jmp @r6
nop
.align 2
10 :
.long PAGE_SIZE
11 :
2006-11-27 06:06:26 +03:00
.long P2SEG
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