1/* 2 * arch/s390/kernel/relocate_kernel.S 3 * 4 * (C) Copyright IBM Corp. 2005 5 * 6 * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> 7 * 8 */ 9 10/* 11 * moves the new kernel to its destination... 12 * %r2 = pointer to first kimage_entry_t 13 * %r3 = start address - where to jump to after the job is done... 14 * 15 * %r5 will be used as temp. storage 16 * %r6 holds the destination address 17 * %r7 = PAGE_SIZE 18 * %r8 holds the source address 19 * %r9 = PAGE_SIZE 20 * %r10 is a page mask 21 */ 22 23 .text 24 .globl relocate_kernel 25 relocate_kernel: 26 basr %r13,0 #base address 27 .base: 28 spx zero64-.base(%r13) #absolute addressing mode 29 stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) 30 lhi %r10,-1 #preparing the mask 31 sll %r10,12 #shift it such that it becomes 0xf000 32 .top: 33 lhi %r7,4096 #load PAGE_SIZE in r7 34 lhi %r9,4096 #load PAGE_SIZE in r9 35 l %r5,0(%r2) #read another word for indirection page 36 ahi %r2,4 #increment pointer 37 tml %r5,0x1 #is it a destination page? 38 je .indir_check #NO, goto "indir_check" 39 lr %r6,%r5 #r6 = r5 40 nr %r6,%r10 #mask it out and... 41 j .top #...next iteration 42 .indir_check: 43 tml %r5,0x2 #is it a indirection page? 44 je .done_test #NO, goto "done_test" 45 nr %r5,%r10 #YES, mask out, 46 lr %r2,%r5 #move it into the right register, 47 j .top #and read next... 48 .done_test: 49 tml %r5,0x4 #is it the done indicator? 50 je .source_test #NO! Well, then it should be the source indicator... 51 j .done #ok, lets finish it here... 52 .source_test: 53 tml %r5,0x8 #it should be a source indicator... 54 je .top #NO, ignore it... 55 lr %r8,%r5 #r8 = r5 56 nr %r8,%r10 #masking 57 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 58 jo 0b 59 j .top 60 .done: 61 sr %r0,%r0 #clear register r0 62 la %r4,load_psw-.base(%r13) #load psw-address into the register 63 o %r3,4(%r4) #or load address into psw 64 st %r3,4(%r4) 65 mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 66 sr %r1,%r1 #clear %r1 67 sr %r2,%r2 #clear %r2 68 sigp %r1,%r2,0x12 #set cpuid to zero 69 lpsw 0 #hopefully start new kernel... 70 71 .align 8 72 zero64: 73 .quad 0 74 load_psw: 75 .long 0x00080000,0x80000000 76 sys_msk: 77 .quad 0 78 relocate_kernel_end: 79 .globl relocate_kernel_len 80 relocate_kernel_len: 81 .quad relocate_kernel_end - relocate_kernel 82