0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/linkage.h>
0010 #include <asm/page.h>
0011 #include <asm/sigp.h>
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 .text
0029 ENTRY(relocate_kernel)
0030 basr %r13,0 # base address
0031 .base:
0032 lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7
0033 lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9
0034 lg %r5,0(%r2) # read another word for indirection page
0035 aghi %r2,8 # increment pointer
0036 tml %r5,0x1 # is it a destination page?
0037 je .indir_check # NO, goto "indir_check"
0038 lgr %r6,%r5 # r6 = r5
0039 nill %r6,0xf000 # mask it out and...
0040 j .base # ...next iteration
0041 .indir_check:
0042 tml %r5,0x2 # is it a indirection page?
0043 je .done_test # NO, goto "done_test"
0044 nill %r5,0xf000 # YES, mask out,
0045 lgr %r2,%r5 # move it into the right register,
0046 j .base # and read next...
0047 .done_test:
0048 tml %r5,0x4 # is it the done indicator?
0049 je .source_test # NO! Well, then it should be the source indicator...
0050 j .done # ok, lets finish it here...
0051 .source_test:
0052 tml %r5,0x8 # it should be a source indicator...
0053 je .base # NO, ignore it...
0054 lgr %r8,%r5 # r8 = r5
0055 nill %r8,0xf000 # masking
0056 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
0057 jo 0b
0058 j .base
0059 .done:
0060 lgr %r0,%r4 # subcode
0061 cghi %r3,0
0062 je .diag
0063 la %r4,load_psw-.base(%r13) # load psw-address into the register
0064 o %r3,4(%r4) # or load address into psw
0065 st %r3,4(%r4)
0066 mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
0067 .diag:
0068 diag %r0,%r0,0x308
0069 ENDPROC(relocate_kernel)
0070
0071 .align 8
0072 load_psw:
0073 .long 0x00080000,0x80000000
0074 relocate_kernel_end:
0075 .align 8
0076 .globl relocate_kernel_len
0077 relocate_kernel_len:
0078 .quad relocate_kernel_end - relocate_kernel