~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/riscv/kernel/kexec_relocate.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Copyright (C) 2019 FORTH-ICS/CARV
  4  *  Nick Kossifidis <mick@ics.forth.gr>
  5  */
  6 
  7 #include <asm/asm.h>    /* For RISCV_* and REG_* macros */
  8 #include <asm/csr.h>    /* For CSR_* macros */
  9 #include <asm/page.h>   /* For PAGE_SIZE */
 10 #include <linux/linkage.h> /* For SYM_* macros */
 11 
 12 .section ".rodata"
 13 SYM_CODE_START(riscv_kexec_relocate)
 14 
 15         /*
 16          * s0: Pointer to the current entry
 17          * s1: (const) Phys address to jump to after relocation
 18          * s2: (const) Phys address of the FDT image
 19          * s3: (const) The hartid of the current hart
 20          * s4: (const) kernel_map.va_pa_offset, used when switching MMU off
 21          * s5: Pointer to the destination address for the relocation
 22          * s6: (const) Physical address of the main loop
 23          */
 24         mv      s0, a0
 25         mv      s1, a1
 26         mv      s2, a2
 27         mv      s3, a3
 28         mv      s4, a4
 29         mv      s5, zero
 30         mv      s6, zero
 31 
 32         /* Disable / cleanup interrupts */
 33         csrw    CSR_SIE, zero
 34         csrw    CSR_SIP, zero
 35 
 36         /*
 37          * When we switch SATP.MODE to "Bare" we'll only
 38          * play with physical addresses. However the first time
 39          * we try to jump somewhere, the offset on the jump
 40          * will be relative to pc which will still be on VA. To
 41          * deal with this we set stvec to the physical address at
 42          * the start of the loop below so that we jump there in
 43          * any case.
 44          */
 45         la      s6, 1f
 46         sub     s6, s6, s4
 47         csrw    CSR_STVEC, s6
 48 
 49         /*
 50          * With C-extension, here we get 42 Bytes and the next
 51          * .align directive would pad zeros here up to 44 Bytes.
 52          * So manually put a nop here to avoid zeros padding.
 53         */
 54         nop
 55 
 56         /* Process entries in a loop */
 57 .align 2
 58 1:
 59         REG_L   t0, 0(s0)               /* t0 = *image->entry */
 60         addi    s0, s0, RISCV_SZPTR     /* image->entry++ */
 61 
 62         /* IND_DESTINATION entry ? -> save destination address */
 63         andi    t1, t0, 0x1
 64         beqz    t1, 2f
 65         andi    s5, t0, ~0x1
 66         j       1b
 67 
 68 2:
 69         /* IND_INDIRECTION entry ? -> update next entry ptr (PA) */
 70         andi    t1, t0, 0x2
 71         beqz    t1, 2f
 72         andi    s0, t0, ~0x2
 73         csrw    CSR_SATP, zero
 74         jr      s6
 75 
 76 2:
 77         /* IND_DONE entry ? -> jump to done label */
 78         andi    t1, t0, 0x4
 79         beqz    t1, 2f
 80         j       4f
 81 
 82 2:
 83         /*
 84          * IND_SOURCE entry ? -> copy page word by word to the
 85          * destination address we got from IND_DESTINATION
 86          */
 87         andi    t1, t0, 0x8
 88         beqz    t1, 1b          /* Unknown entry type, ignore it */
 89         andi    t0, t0, ~0x8
 90         li      t3, (PAGE_SIZE / RISCV_SZPTR)   /* i = num words per page */
 91 3:      /* copy loop */
 92         REG_L   t1, (t0)        /* t1 = *src_ptr */
 93         REG_S   t1, (s5)        /* *dst_ptr = *src_ptr */
 94         addi    t0, t0, RISCV_SZPTR /* stc_ptr++ */
 95         addi    s5, s5, RISCV_SZPTR /* dst_ptr++ */
 96         addi    t3, t3, -0x1    /* i-- */
 97         beqz    t3, 1b          /* copy done ? */
 98         j       3b
 99 
100 4:
101         /* Pass the arguments to the next kernel  / Cleanup*/
102         mv      a0, s3
103         mv      a1, s2
104         mv      a2, s1
105 
106         /* Cleanup */
107         mv      a3, zero
108         mv      a4, zero
109         mv      a5, zero
110         mv      a6, zero
111         mv      a7, zero
112 
113         mv      s0, zero
114         mv      s1, zero
115         mv      s2, zero
116         mv      s3, zero
117         mv      s4, zero
118         mv      s5, zero
119         mv      s6, zero
120         mv      s7, zero
121         mv      s8, zero
122         mv      s9, zero
123         mv      s10, zero
124         mv      s11, zero
125 
126         mv      t0, zero
127         mv      t1, zero
128         mv      t2, zero
129         mv      t3, zero
130         mv      t4, zero
131         mv      t5, zero
132         mv      t6, zero
133         csrw    CSR_SEPC, zero
134         csrw    CSR_SCAUSE, zero
135         csrw    CSR_SSCRATCH, zero
136 
137         /*
138          * Make sure the relocated code is visible
139          * and jump to the new kernel
140          */
141         fence.i
142 
143         jr      a2
144 
145 SYM_CODE_END(riscv_kexec_relocate)
146 riscv_kexec_relocate_end:
147 
148 
149 /* Used for jumping to crashkernel */
150 .section ".text"
151 SYM_CODE_START(riscv_kexec_norelocate)
152         /*
153          * s0: (const) Phys address to jump to
154          * s1: (const) Phys address of the FDT image
155          * s2: (const) The hartid of the current hart
156          */
157         mv      s0, a1
158         mv      s1, a2
159         mv      s2, a3
160 
161         /* Disable / cleanup interrupts */
162         csrw    CSR_SIE, zero
163         csrw    CSR_SIP, zero
164 
165         /* Pass the arguments to the next kernel  / Cleanup*/
166         mv      a0, s2
167         mv      a1, s1
168         mv      a2, s0
169 
170         /* Cleanup */
171         mv      a3, zero
172         mv      a4, zero
173         mv      a5, zero
174         mv      a6, zero
175         mv      a7, zero
176 
177         mv      s0, zero
178         mv      s1, zero
179         mv      s2, zero
180         mv      s3, zero
181         mv      s4, zero
182         mv      s5, zero
183         mv      s6, zero
184         mv      s7, zero
185         mv      s8, zero
186         mv      s9, zero
187         mv      s10, zero
188         mv      s11, zero
189 
190         mv      t0, zero
191         mv      t1, zero
192         mv      t2, zero
193         mv      t3, zero
194         mv      t4, zero
195         mv      t5, zero
196         mv      t6, zero
197         csrw    CSR_SEPC, zero
198         csrw    CSR_SCAUSE, zero
199         csrw    CSR_SSCRATCH, zero
200 
201         /*
202          * Switch to physical addressing
203          * This will also trigger a jump to CSR_STVEC
204          * which in this case is the address of the new
205          * kernel.
206          */
207         csrw    CSR_STVEC, a2
208         csrw    CSR_SATP, zero
209 
210 SYM_CODE_END(riscv_kexec_norelocate)
211 
212 .section ".rodata"
213 SYM_DATA(riscv_kexec_relocate_size,
214         .long riscv_kexec_relocate_end - riscv_kexec_relocate)
215 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php