Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / arch / s390 / kernel / relocate_kernel.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright IBM Corp. 2005
4  *
5  * Author(s): Rolf Adelsberger,
6  *            Heiko Carstens <heiko.carstens@de.ibm.com>
7  *
8  */
9
10 #include <linux/linkage.h>
11 #include <asm/page.h>
12 #include <asm/sigp.h>
13
14 /*
15  * moves the new kernel to its destination...
16  * %r2 = pointer to first kimage_entry_t
17  * %r3 = start address - where to jump to after the job is done...
18  *
19  * %r5 will be used as temp. storage
20  * %r6 holds the destination address
21  * %r7 = PAGE_SIZE
22  * %r8 holds the source address
23  * %r9 = PAGE_SIZE
24  *
25  * 0xf000 is a page_mask
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