Back to home page

LXR

 
 

    


0001 /*
0002  * Copyright IBM Corp. 2005
0003  *
0004  * Author(s): Rolf Adelsberger,
0005  *        Heiko Carstens <heiko.carstens@de.ibm.com>
0006  *
0007  */
0008 
0009 #include <linux/linkage.h>
0010 #include <asm/sigp.h>
0011 
0012 /*
0013  * moves the new kernel to its destination...
0014  * %r2 = pointer to first kimage_entry_t
0015  * %r3 = start address - where to jump to after the job is done...
0016  *
0017  * %r5 will be used as temp. storage
0018  * %r6 holds the destination address
0019  * %r7 = PAGE_SIZE
0020  * %r8 holds the source address
0021  * %r9 = PAGE_SIZE
0022  *
0023  * 0xf000 is a page_mask
0024  */
0025 
0026     .text
0027 ENTRY(relocate_kernel)
0028         basr    %r13,0      # base address
0029     .base:
0030         stnsm   sys_msk-.base(%r13),0xfb    # disable DAT
0031         stctg   %c0,%c15,ctlregs-.base(%r13)
0032         stmg    %r0,%r15,gprregs-.base(%r13)
0033         lghi    %r0,3
0034         sllg    %r0,%r0,31
0035         stg %r0,0x1d0(%r0)
0036         la  %r0,.back_pgm-.base(%r13)
0037         stg %r0,0x1d8(%r0)
0038         la  %r1,load_psw-.base(%r13)
0039         mvc 0(8,%r0),0(%r1)
0040         la  %r0,.back-.base(%r13)
0041         st  %r0,4(%r0)
0042         oi  4(%r0),0x80
0043         lghi    %r0,0
0044         diag    %r0,%r0,0x308
0045     .back:
0046         lhi %r1,1       # mode 1 = esame
0047         sigp    %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esame mode
0048         sam64           # switch to 64 bit addressing mode
0049         basr    %r13,0
0050     .back_base:
0051         oi  have_diag308-.back_base(%r13),0x01
0052         lctlg   %c0,%c15,ctlregs-.back_base(%r13)
0053         lmg %r0,%r15,gprregs-.back_base(%r13)
0054         j   .top
0055     .back_pgm:
0056         lmg %r0,%r15,gprregs-.base(%r13)
0057     .top:
0058         lghi    %r7,4096    # load PAGE_SIZE in r7
0059         lghi    %r9,4096    # load PAGE_SIZE in r9
0060         lg  %r5,0(%r2)  # read another word for indirection page
0061         aghi    %r2,8       # increment pointer
0062         tml %r5,0x1     # is it a destination page?
0063         je  .indir_check    # NO, goto "indir_check"
0064         lgr %r6,%r5     # r6 = r5
0065         nill    %r6,0xf000  # mask it out and...
0066         j   .top        # ...next iteration
0067     .indir_check:
0068         tml %r5,0x2     # is it a indirection page?
0069         je  .done_test  # NO, goto "done_test"
0070         nill    %r5,0xf000  # YES, mask out,
0071         lgr %r2,%r5     # move it into the right register,
0072         j   .top        # and read next...
0073     .done_test:
0074         tml %r5,0x4     # is it the done indicator?
0075         je  .source_test    # NO! Well, then it should be the source indicator...
0076         j   .done       # ok, lets finish it here...
0077     .source_test:
0078         tml %r5,0x8     # it should be a source indicator...
0079         je  .top        # NO, ignore it...
0080         lgr %r8,%r5     # r8 = r5
0081         nill    %r8,0xf000  # masking
0082     0:  mvcle   %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
0083         jo  0b
0084         j   .top
0085     .done:
0086         sgr %r0,%r0     # clear register r0
0087         la  %r4,load_psw-.base(%r13)    # load psw-address into the register
0088         o   %r3,4(%r4)  # or load address into psw
0089         st  %r3,4(%r4)
0090         mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
0091         tm  have_diag308-.base(%r13),0x01
0092         jno .no_diag308
0093         diag    %r0,%r0,0x308
0094     .no_diag308:
0095         sam31           # 31 bit mode
0096         sr  %r1,%r1     # erase register r1
0097         sr  %r2,%r2     # erase register r2
0098         sigp    %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero
0099         lpsw    0       # hopefully start new kernel...
0100 
0101         .align  8
0102     load_psw:
0103         .long   0x00080000,0x80000000
0104     sys_msk:
0105         .quad   0
0106     ctlregs:
0107         .rept   16
0108         .quad   0
0109         .endr
0110     gprregs:
0111         .rept   16
0112         .quad   0
0113         .endr
0114     have_diag308:
0115         .byte   0
0116         .align  8
0117     relocate_kernel_end:
0118     .align 8
0119     .globl  relocate_kernel_len
0120     relocate_kernel_len:
0121         .quad   relocate_kernel_end - relocate_kernel