1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <linux/linkage.h>
  11 #include <asm/page.h>
  12 #include <asm/sigp.h>
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28         .text
  29 ENTRY(relocate_kernel)
  30                 basr    %r13,0          # base address
  31         .base:
  32                 lghi    %r7,PAGE_SIZE   # load PAGE_SIZE in r7
  33                 lghi    %r9,PAGE_SIZE   # load PAGE_SIZE in r9
  34                 lg      %r5,0(%r2)      # read another word for indirection page
  35                 aghi    %r2,8           # increment pointer
  36                 tml     %r5,0x1         # is it a destination page?
  37                 je      .indir_check    # NO, goto "indir_check"
  38                 lgr     %r6,%r5         # r6 = r5
  39                 nill    %r6,0xf000      # mask it out and...
  40                 j       .base           # ...next iteration
  41         .indir_check:
  42                 tml     %r5,0x2         # is it a indirection page?
  43                 je      .done_test      # NO, goto "done_test"
  44                 nill    %r5,0xf000      # YES, mask out,
  45                 lgr     %r2,%r5         # move it into the right register,
  46                 j       .base           # and read next...
  47         .done_test:
  48                 tml     %r5,0x4         # is it the done indicator?
  49                 je      .source_test    # NO! Well, then it should be the source indicator...
  50                 j       .done           # ok, lets finish it here...
  51         .source_test:
  52                 tml     %r5,0x8         # it should be a source indicator...
  53                 je      .base           # NO, ignore it...
  54                 lgr     %r8,%r5         # r8 = r5
  55                 nill    %r8,0xf000      # masking
  56         0:      mvcle   %r6,%r8,0x0     # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
  57                 jo      0b
  58                 j       .base
  59         .done:
  60                 sgr     %r0,%r0         # clear register r0
  61                 cghi    %r3,0
  62                 je      .diag
  63                 la      %r4,load_psw-.base(%r13)        # load psw-address into the register
  64                 o       %r3,4(%r4)      # or load address into psw
  65                 st      %r3,4(%r4)
  66                 mvc     0(8,%r0),0(%r4) # copy psw to absolute address 0
  67         .diag:
  68                 diag    %r0,%r0,0x308
  69 ENDPROC(relocate_kernel)
  70 
  71                 .align  8
  72         load_psw:
  73                 .long   0x00080000,0x80000000
  74         relocate_kernel_end:
  75         .align 8
  76         .globl  relocate_kernel_len
  77         relocate_kernel_len:
  78                 .quad   relocate_kernel_end - relocate_kernel