2 * arch/ia64/kernel/relocate_kernel.S
4 * Relocate kexec'able kernel and start it
6 * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
7 * Copyright (C) 2005 Khalid Aziz <khalid.aziz@hp.com>
8 * Copyright (C) 2005 Intel Corp, Zou Nan hai <nanhai.zou@intel.com>
10 * This source code is licensed under the GNU General Public License,
11 * Version 2. See the file COPYING for more details.
13 #include <asm/asmmacro.h>
14 #include <asm/kregs.h>
16 #include <asm/pgtable.h>
17 #include <asm/mca_asm.h>
19 /* Must be relocatable PIC code callable as a C function
21 GLOBAL_ENTRY(relocate_new_kernel)
23 alloc r31=ar.pfs,4,0,0,0
32 flushrs // must be first insn in group
36 dep r2=0,r2,61,3 //to physical address
38 //first switch to physical mode
39 add r3=1f-.reloc_entry, r2
40 movl r16 = IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_IC
41 mov ar.rsc=0 // put RSE in enforced lazy mode
43 add sp=(memory_stack_end - 16 - .reloc_entry),r2
44 add r8=(register_stack - .reloc_entry),r2
58 //physical mode code begin
60 dep r28=0,in2,61,3 //to physical address
62 // purge all TC entries
63 #define O(member) IA64_CPUINFO_##member##_OFFSET
64 GET_THIS_PADDR(r2, cpu_info) // load phys addr of cpu_info into r2
66 addl r17=O(PTCE_STRIDE),r2
67 addl r2=O(PTCE_BASE),r2
69 ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base
70 ld4 r19=[r2],4 // r19=ptce_count[0]
71 ld4 r21=[r17],4 // r21=ptce_stride[0]
73 ld4 r20=[r2] // r20=ptce_count[1]
74 ld4 r22=[r17] // r22=ptce_stride[1]
82 (p7) br.cond.dpnt.few 4f
97 //purge TR entry for kernel text and data
99 mov r18=KERNEL_TR_PAGE_SHIFT<<2
107 // purge TR entry for percpu data
109 mov r18=PERCPU_PAGE_SHIFT<<2
116 // purge TR entry for pal code
118 mov r18=IA64_GRANULE_SHIFT<<2
125 // purge TR entry for stack
126 mov r16=IA64_KR(CURRENT_STACK)
128 shl r16=r16,IA64_GRANULE_SHIFT
132 mov r18=IA64_GRANULE_SHIFT<<2
141 mov r30=in0 // in0 is page_list
142 br.sptk.few .dest_page
147 tbit.z p0, p6=r30, 0;; // 0x1 dest page
148 (p6) and r17=r30, r16
149 (p6) br.cond.sptk.few .loop;;
151 tbit.z p0, p6=r30, 1;; // 0x2 indirect page
152 (p6) and in0=r30, r16
153 (p6) br.cond.sptk.few .loop;;
155 tbit.z p0, p6=r30, 2;; // 0x4 end flag
156 (p6) br.cond.sptk.few .end_loop;;
158 tbit.z p6, p0=r30, 3;; // 0x8 source page
159 (p6) br.cond.sptk.few .loop
163 // simple copy page, may optimize later
164 movl r14=PAGE_SIZE/8 - 1;;
182 br.call.sptk.many b0=b6;;
191 relocate_new_kernel_end:
192 END(relocate_new_kernel)
194 .global relocate_new_kernel_size
195 relocate_new_kernel_size:
196 data8 relocate_new_kernel_end - relocate_new_kernel
198 GLOBAL_ENTRY(ia64_dump_cpu_regs)
200 alloc loc0=ar.pfs,1,2,0,0
202 mov ar.rsc=0 // put RSE in enforced lazy mode
203 add loc1=4*8, in0 // save r4 and r5 first
206 flushrs // flush dirty regs to backing store
216 st8 [in0]=r0, 8 // r0
217 st8 [loc1]=r4, 8 // rnat
220 st8 [in0]=r1, 8 // r1
221 st8 [loc1]=r5, 8 // pr
224 st8 [in0]=r2, 8 // r2
225 st8 [loc1]=r4, 8 // b0
228 st8 [in0]=r3, 24 // r3
229 st8 [loc1]=r5, 8 // b1
232 st8 [in0]=r6, 8 // r6
233 st8 [loc1]=r4, 8 // b2
236 st8 [in0]=r7, 8 // r7
237 st8 [loc1]=r5, 8 // b3
240 st8 [in0]=r8, 8 // r8
241 st8 [loc1]=r4, 8 // b4
244 st8 [in0]=r9, 8 // r9
245 st8 [loc1]=r5, 8 // b5
248 st8 [in0]=r10, 8 // r10
249 st8 [loc1]=r5, 8 // b6
252 st8 [in0]=r11, 8 // r11
253 st8 [loc1]=r5, 8 // b7
256 st8 [in0]=r12, 8 // r12
257 st8 [loc1]=r4, 8 // ip
260 st8 [in0]=r13, 8 // r13
261 extr.u r5=r5, 0, 38 // ar.pfs.pfm
262 mov r4=r0 // user mask
264 st8 [in0]=r14, 8 // r14
265 st8 [loc1]=r5, 8 // cfm
267 st8 [in0]=r15, 8 // r15
268 st8 [loc1]=r4, 8 // user mask
271 st8 [in0]=r16, 8 // r16
272 st8 [loc1]=r5, 8 // ar.rsc
275 st8 [in0]=r17, 8 // r17
276 st8 [loc1]=r4, 8 // ar.bsp
279 st8 [in0]=r18, 8 // r18
280 st8 [loc1]=r5, 8 // ar.bspstore
283 st8 [in0]=r19, 8 // r19
284 st8 [loc1]=r4, 8 // ar.rnat
287 st8 [in0]=r20, 8 // r20
288 st8 [loc1]=r5, 8 // ar.ccv
291 st8 [in0]=r21, 8 // r21
292 st8 [loc1]=r4, 8 // ar.unat
295 st8 [in0]=r22, 8 // r22
296 st8 [loc1]=r5, 8 // ar.fpsr
299 st8 [in0]=r23, 8 // r23
300 st8 [loc1]=r4, 8 // unat
303 st8 [in0]=r24, 8 // r24
304 st8 [loc1]=r5, 8 // fpsr
307 st8 [in0]=r25, 8 // r25
308 st8 [loc1]=r4, 8 // ar.pfs
311 st8 [in0]=r26, 8 // r26
312 st8 [loc1]=r5, 8 // ar.lc
315 st8 [in0]=r27, 8 // r27
316 st8 [loc1]=r4, 8 // ar.ec
319 st8 [in0]=r28, 8 // r28
320 st8 [loc1]=r5, 8 // ar.csd
323 st8 [in0]=r29, 8 // r29
324 st8 [loc1]=r4, 8 // ar.ssd
326 st8 [in0]=r30, 8 // r30
328 st8 [in0]=r31, 8 // r31
332 END(ia64_dump_cpu_regs)