Back to home page

LXR

 
 

    


0001 /*
0002  * arch/ia64/kernel/relocate_kernel.S
0003  *
0004  * Relocate kexec'able kernel and start it
0005  *
0006  * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
0007  * Copyright (C) 2005 Khalid Aziz  <khalid.aziz@hp.com>
0008  * Copyright (C) 2005 Intel Corp,  Zou Nan hai <nanhai.zou@intel.com>
0009  *
0010  * This source code is licensed under the GNU General Public License,
0011  * Version 2.  See the file COPYING for more details.
0012  */
0013 #include <asm/asmmacro.h>
0014 #include <asm/kregs.h>
0015 #include <asm/page.h>
0016 #include <asm/pgtable.h>
0017 #include <asm/mca_asm.h>
0018 
0019        /* Must be relocatable PIC code callable as a C function
0020         */
0021 GLOBAL_ENTRY(relocate_new_kernel)
0022     .prologue
0023     alloc r31=ar.pfs,4,0,0,0
0024         .body
0025 .reloc_entry:
0026 {
0027     rsm psr.i| psr.ic
0028     mov r2=ip
0029 }
0030     ;;
0031 {
0032         flushrs                         // must be first insn in group
0033         srlz.i
0034 }
0035     ;;
0036     dep r2=0,r2,61,3        //to physical address
0037     ;;
0038     //first switch to physical mode
0039     add r3=1f-.reloc_entry, r2
0040     movl r16 = IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_IC
0041     mov ar.rsc=0                // put RSE in enforced lazy mode
0042     ;;
0043     add sp=(memory_stack_end - 16 - .reloc_entry),r2
0044     add r8=(register_stack - .reloc_entry),r2
0045     ;;
0046     mov r18=ar.rnat
0047     mov ar.bspstore=r8
0048     ;;
0049         mov cr.ipsr=r16
0050         mov cr.iip=r3
0051         mov cr.ifs=r0
0052     srlz.i
0053     ;;
0054     mov ar.rnat=r18
0055     rfi             // note: this unmask MCA/INIT (psr.mc)
0056     ;;
0057 1:
0058     //physical mode code begin
0059     mov b6=in1
0060     dep r28=0,in2,61,3  //to physical address
0061 
0062     // purge all TC entries
0063 #define O(member)       IA64_CPUINFO_##member##_OFFSET
0064         GET_THIS_PADDR(r2, ia64_cpu_info) // load phys addr of cpu_info into r2
0065         ;;
0066         addl r17=O(PTCE_STRIDE),r2
0067         addl r2=O(PTCE_BASE),r2
0068         ;;
0069         ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));;     // r18=ptce_base
0070         ld4 r19=[r2],4                                  // r19=ptce_count[0]
0071         ld4 r21=[r17],4                                 // r21=ptce_stride[0]
0072         ;;
0073         ld4 r20=[r2]                                    // r20=ptce_count[1]
0074         ld4 r22=[r17]                                   // r22=ptce_stride[1]
0075         mov r24=r0
0076         ;;
0077         adds r20=-1,r20
0078         ;;
0079 #undef O
0080 2:
0081         cmp.ltu p6,p7=r24,r19
0082 (p7)    br.cond.dpnt.few 4f
0083         mov ar.lc=r20
0084 3:
0085         ptc.e r18
0086         ;;
0087         add r18=r22,r18
0088         br.cloop.sptk.few 3b
0089         ;;
0090         add r18=r21,r18
0091         add r24=1,r24
0092         ;;
0093         br.sptk.few 2b
0094 4:
0095         srlz.i
0096         ;;
0097     // purge TR entry for kernel text and data
0098         movl r16=KERNEL_START
0099         mov r18=KERNEL_TR_PAGE_SHIFT<<2
0100         ;;
0101         ptr.i r16, r18
0102         ptr.d r16, r18
0103         ;;
0104         srlz.i
0105         ;;
0106 
0107         // purge TR entry for pal code
0108         mov r16=in3
0109         mov r18=IA64_GRANULE_SHIFT<<2
0110         ;;
0111         ptr.i r16,r18
0112         ;;
0113         srlz.i
0114     ;;
0115 
0116         // purge TR entry for stack
0117         mov r16=IA64_KR(CURRENT_STACK)
0118         ;;
0119         shl r16=r16,IA64_GRANULE_SHIFT
0120         movl r19=PAGE_OFFSET
0121         ;;
0122         add r16=r19,r16
0123         mov r18=IA64_GRANULE_SHIFT<<2
0124         ;;
0125         ptr.d r16,r18
0126         ;;
0127         srlz.i
0128     ;;
0129 
0130     //copy segments
0131     movl r16=PAGE_MASK
0132         mov  r30=in0                    // in0 is page_list
0133         br.sptk.few .dest_page
0134     ;;
0135 .loop:
0136     ld8  r30=[in0], 8;;
0137 .dest_page:
0138     tbit.z p0, p6=r30, 0;;      // 0x1 dest page
0139 (p6)    and r17=r30, r16
0140 (p6)    br.cond.sptk.few .loop;;
0141 
0142     tbit.z p0, p6=r30, 1;;      // 0x2 indirect page
0143 (p6)    and in0=r30, r16
0144 (p6)    br.cond.sptk.few .loop;;
0145 
0146     tbit.z p0, p6=r30, 2;;      // 0x4 end flag
0147 (p6)    br.cond.sptk.few .end_loop;;
0148 
0149     tbit.z p6, p0=r30, 3;;      // 0x8 source page
0150 (p6)    br.cond.sptk.few .loop
0151 
0152     and r18=r30, r16
0153 
0154     // simple copy page, may optimize later
0155     movl r14=PAGE_SIZE/8 - 1;;
0156     mov ar.lc=r14;;
0157 1:
0158     ld8 r14=[r18], 8;;
0159     st8 [r17]=r14;;
0160     fc.i r17
0161     add r17=8, r17
0162     br.ctop.sptk.few 1b
0163     br.sptk.few .loop
0164     ;;
0165 
0166 .end_loop:
0167     sync.i          // for fc.i
0168     ;;
0169     srlz.i
0170     ;;
0171     srlz.d
0172     ;;
0173     br.call.sptk.many b0=b6;;
0174 
0175 .align  32
0176 memory_stack:
0177     .fill           8192, 1, 0
0178 memory_stack_end:
0179 register_stack:
0180     .fill           8192, 1, 0
0181 register_stack_end:
0182 relocate_new_kernel_end:
0183 END(relocate_new_kernel)
0184 
0185 .global relocate_new_kernel_size
0186 relocate_new_kernel_size:
0187     data8   relocate_new_kernel_end - relocate_new_kernel
0188 
0189 GLOBAL_ENTRY(ia64_dump_cpu_regs)
0190         .prologue
0191         alloc loc0=ar.pfs,1,2,0,0
0192         .body
0193         mov     ar.rsc=0                // put RSE in enforced lazy mode
0194         add     loc1=4*8, in0           // save r4 and r5 first
0195         ;;
0196 {
0197         flushrs                         // flush dirty regs to backing store
0198         srlz.i
0199 }
0200         st8 [loc1]=r4, 8
0201         ;;
0202         st8 [loc1]=r5, 8
0203         ;;
0204         add loc1=32*8, in0
0205         mov r4=ar.rnat
0206         ;;
0207         st8 [in0]=r0, 8         // r0
0208         st8 [loc1]=r4, 8        // rnat
0209         mov r5=pr
0210         ;;
0211         st8 [in0]=r1, 8         // r1
0212         st8 [loc1]=r5, 8        // pr
0213         mov r4=b0
0214         ;;
0215         st8 [in0]=r2, 8         // r2
0216         st8 [loc1]=r4, 8        // b0
0217         mov r5=b1;
0218         ;;
0219         st8 [in0]=r3, 24        // r3
0220         st8 [loc1]=r5, 8        // b1
0221         mov r4=b2
0222         ;;
0223         st8 [in0]=r6, 8         // r6
0224         st8 [loc1]=r4, 8        // b2
0225     mov r5=b3
0226         ;;
0227         st8 [in0]=r7, 8         // r7
0228         st8 [loc1]=r5, 8        // b3
0229         mov r4=b4
0230         ;;
0231         st8 [in0]=r8, 8         // r8
0232         st8 [loc1]=r4, 8        // b4
0233         mov r5=b5
0234         ;;
0235         st8 [in0]=r9, 8         // r9
0236         st8 [loc1]=r5, 8        // b5
0237         mov r4=b6
0238         ;;
0239         st8 [in0]=r10, 8        // r10
0240         st8 [loc1]=r5, 8        // b6
0241         mov r5=b7
0242         ;;
0243         st8 [in0]=r11, 8        // r11
0244         st8 [loc1]=r5, 8        // b7
0245         mov r4=b0
0246         ;;
0247         st8 [in0]=r12, 8        // r12
0248         st8 [loc1]=r4, 8        // ip
0249         mov r5=loc0
0250     ;;
0251         st8 [in0]=r13, 8        // r13
0252         extr.u r5=r5, 0, 38     // ar.pfs.pfm
0253     mov r4=r0           // user mask
0254         ;;
0255         st8 [in0]=r14, 8        // r14
0256         st8 [loc1]=r5, 8        // cfm
0257         ;;
0258         st8 [in0]=r15, 8        // r15
0259         st8 [loc1]=r4, 8            // user mask
0260     mov r5=ar.rsc
0261         ;;
0262         st8 [in0]=r16, 8        // r16
0263         st8 [loc1]=r5, 8            // ar.rsc
0264         mov r4=ar.bsp
0265         ;;
0266         st8 [in0]=r17, 8        // r17
0267         st8 [loc1]=r4, 8            // ar.bsp
0268         mov r5=ar.bspstore
0269         ;;
0270         st8 [in0]=r18, 8        // r18
0271         st8 [loc1]=r5, 8            // ar.bspstore
0272         mov r4=ar.rnat
0273         ;;
0274         st8 [in0]=r19, 8        // r19
0275         st8 [loc1]=r4, 8            // ar.rnat
0276         mov r5=ar.ccv
0277         ;;
0278         st8 [in0]=r20, 8        // r20
0279     st8 [loc1]=r5, 8            // ar.ccv
0280         mov r4=ar.unat
0281         ;;
0282         st8 [in0]=r21, 8        // r21
0283         st8 [loc1]=r4, 8            // ar.unat
0284         mov r5 = ar.fpsr
0285         ;;
0286         st8 [in0]=r22, 8        // r22
0287         st8 [loc1]=r5, 8            // ar.fpsr
0288         mov r4 = ar.unat
0289         ;;
0290         st8 [in0]=r23, 8        // r23
0291         st8 [loc1]=r4, 8            // unat
0292         mov r5 = ar.fpsr
0293         ;;
0294         st8 [in0]=r24, 8        // r24
0295         st8 [loc1]=r5, 8            // fpsr
0296         mov r4 = ar.pfs
0297         ;;
0298         st8 [in0]=r25, 8        // r25
0299         st8 [loc1]=r4, 8            // ar.pfs
0300         mov r5 = ar.lc
0301         ;;
0302         st8 [in0]=r26, 8        // r26
0303         st8 [loc1]=r5, 8            // ar.lc
0304         mov r4 = ar.ec
0305         ;;
0306         st8 [in0]=r27, 8        // r27
0307         st8 [loc1]=r4, 8            // ar.ec
0308         mov r5 = ar.csd
0309         ;;
0310         st8 [in0]=r28, 8        // r28
0311         st8 [loc1]=r5, 8            // ar.csd
0312         mov r4 = ar.ssd
0313         ;;
0314         st8 [in0]=r29, 8        // r29
0315         st8 [loc1]=r4, 8            // ar.ssd
0316         ;;
0317         st8 [in0]=r30, 8        // r30
0318         ;;
0319     st8 [in0]=r31, 8        // r31
0320         mov ar.pfs=loc0
0321         ;;
0322         br.ret.sptk.many rp
0323 END(ia64_dump_cpu_regs)
0324 
0325