linux/arch/ia64/kernel/relocate_kernel.S
<<
>>
Prefs
   1/*
   2 * arch/ia64/kernel/relocate_kernel.S
   3 *
   4 * Relocate kexec'able kernel and start it
   5 *
   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>
   9 *
  10 * This source code is licensed under the GNU General Public License,
  11 * Version 2.  See the file COPYING for more details.
  12 */
  13#include <asm/asmmacro.h>
  14#include <asm/kregs.h>
  15#include <asm/page.h>
  16#include <asm/pgtable.h>
  17#include <asm/mca_asm.h>
  18
  19       /* Must be relocatable PIC code callable as a C function
  20        */
  21GLOBAL_ENTRY(relocate_new_kernel)
  22        .prologue
  23        alloc r31=ar.pfs,4,0,0,0
  24        .body
  25.reloc_entry:
  26{
  27        rsm psr.i| psr.ic
  28        mov r2=ip
  29}
  30        ;;
  31{
  32        flushrs                         // must be first insn in group
  33        srlz.i
  34}
  35        ;;
  36        dep r2=0,r2,61,3                //to physical address
  37        ;;
  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
  42        ;;
  43        add sp=(memory_stack_end - 16 - .reloc_entry),r2
  44        add r8=(register_stack - .reloc_entry),r2
  45        ;;
  46        mov r18=ar.rnat
  47        mov ar.bspstore=r8
  48        ;;
  49        mov cr.ipsr=r16
  50        mov cr.iip=r3
  51        mov cr.ifs=r0
  52        srlz.i
  53        ;;
  54        mov ar.rnat=r18
  55        rfi                             // note: this unmask MCA/INIT (psr.mc)
  56        ;;
  571:
  58        //physical mode code begin
  59        mov b6=in1
  60        dep r28=0,in2,61,3      //to physical address
  61
  62        // purge all TC entries
  63#define O(member)       IA64_CPUINFO_##member##_OFFSET
  64        GET_THIS_PADDR(r2, ia64_cpu_info) // load phys addr of cpu_info into r2
  65        ;;
  66        addl r17=O(PTCE_STRIDE),r2
  67        addl r2=O(PTCE_BASE),r2
  68        ;;
  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]
  72        ;;
  73        ld4 r20=[r2]                                    // r20=ptce_count[1]
  74        ld4 r22=[r17]                                   // r22=ptce_stride[1]
  75        mov r24=r0
  76        ;;
  77        adds r20=-1,r20
  78        ;;
  79#undef O
  802:
  81        cmp.ltu p6,p7=r24,r19
  82(p7)    br.cond.dpnt.few 4f
  83        mov ar.lc=r20
  843:
  85        ptc.e r18
  86        ;;
  87        add r18=r22,r18
  88        br.cloop.sptk.few 3b
  89        ;;
  90        add r18=r21,r18
  91        add r24=1,r24
  92        ;;
  93        br.sptk.few 2b
  944:
  95        srlz.i
  96        ;;
  97        // purge TR entry for kernel text and data
  98        movl r16=KERNEL_START
  99        mov r18=KERNEL_TR_PAGE_SHIFT<<2
 100        ;;
 101        ptr.i r16, r18
 102        ptr.d r16, r18
 103        ;;
 104        srlz.i
 105        ;;
 106
 107        // purge TR entry for pal code
 108        mov r16=in3
 109        mov r18=IA64_GRANULE_SHIFT<<2
 110        ;;
 111        ptr.i r16,r18
 112        ;;
 113        srlz.i
 114        ;;
 115
 116        // purge TR entry for stack
 117        mov r16=IA64_KR(CURRENT_STACK)
 118        ;;
 119        shl r16=r16,IA64_GRANULE_SHIFT
 120        movl r19=PAGE_OFFSET
 121        ;;
 122        add r16=r19,r16
 123        mov r18=IA64_GRANULE_SHIFT<<2
 124        ;;
 125        ptr.d r16,r18
 126        ;;
 127        srlz.i
 128        ;;
 129
 130        //copy segments
 131        movl r16=PAGE_MASK
 132        mov  r30=in0                    // in0 is page_list
 133        br.sptk.few .dest_page
 134        ;;
 135.loop:
 136        ld8  r30=[in0], 8;;
 137.dest_page:
 138        tbit.z p0, p6=r30, 0;;          // 0x1 dest page
 139(p6)    and r17=r30, r16
 140(p6)    br.cond.sptk.few .loop;;
 141
 142        tbit.z p0, p6=r30, 1;;          // 0x2 indirect page
 143(p6)    and in0=r30, r16
 144(p6)    br.cond.sptk.few .loop;;
 145
 146        tbit.z p0, p6=r30, 2;;          // 0x4 end flag
 147(p6)    br.cond.sptk.few .end_loop;;
 148
 149        tbit.z p6, p0=r30, 3;;          // 0x8 source page
 150(p6)    br.cond.sptk.few .loop
 151
 152        and r18=r30, r16
 153
 154        // simple copy page, may optimize later
 155        movl r14=PAGE_SIZE/8 - 1;;
 156        mov ar.lc=r14;;
 1571:
 158        ld8 r14=[r18], 8;;
 159        st8 [r17]=r14;;
 160        fc.i r17
 161        add r17=8, r17
 162        br.ctop.sptk.few 1b
 163        br.sptk.few .loop
 164        ;;
 165
 166.end_loop:
 167        sync.i                  // for fc.i
 168        ;;
 169        srlz.i
 170        ;;
 171        srlz.d
 172        ;;
 173        br.call.sptk.many b0=b6;;
 174
 175.align  32
 176memory_stack:
 177        .fill           8192, 1, 0
 178memory_stack_end:
 179register_stack:
 180        .fill           8192, 1, 0
 181register_stack_end:
 182relocate_new_kernel_end:
 183END(relocate_new_kernel)
 184
 185.global relocate_new_kernel_size
 186relocate_new_kernel_size:
 187        data8   relocate_new_kernel_end - relocate_new_kernel
 188
 189GLOBAL_ENTRY(ia64_dump_cpu_regs)
 190        .prologue
 191        alloc loc0=ar.pfs,1,2,0,0
 192        .body
 193        mov     ar.rsc=0                // put RSE in enforced lazy mode
 194        add     loc1=4*8, in0           // save r4 and r5 first
 195        ;;
 196{
 197        flushrs                         // flush dirty regs to backing store
 198        srlz.i
 199}
 200        st8 [loc1]=r4, 8
 201        ;;
 202        st8 [loc1]=r5, 8
 203        ;;
 204        add loc1=32*8, in0
 205        mov r4=ar.rnat
 206        ;;
 207        st8 [in0]=r0, 8                 // r0
 208        st8 [loc1]=r4, 8                // rnat
 209        mov r5=pr
 210        ;;
 211        st8 [in0]=r1, 8                 // r1
 212        st8 [loc1]=r5, 8                // pr
 213        mov r4=b0
 214        ;;
 215        st8 [in0]=r2, 8                 // r2
 216        st8 [loc1]=r4, 8                // b0
 217        mov r5=b1;
 218        ;;
 219        st8 [in0]=r3, 24                // r3
 220        st8 [loc1]=r5, 8                // b1
 221        mov r4=b2
 222        ;;
 223        st8 [in0]=r6, 8                 // r6
 224        st8 [loc1]=r4, 8                // b2
 225        mov r5=b3
 226        ;;
 227        st8 [in0]=r7, 8                 // r7
 228        st8 [loc1]=r5, 8                // b3
 229        mov r4=b4
 230        ;;
 231        st8 [in0]=r8, 8                 // r8
 232        st8 [loc1]=r4, 8                // b4
 233        mov r5=b5
 234        ;;
 235        st8 [in0]=r9, 8                 // r9
 236        st8 [loc1]=r5, 8                // b5
 237        mov r4=b6
 238        ;;
 239        st8 [in0]=r10, 8                // r10
 240        st8 [loc1]=r5, 8                // b6
 241        mov r5=b7
 242        ;;
 243        st8 [in0]=r11, 8                // r11
 244        st8 [loc1]=r5, 8                // b7
 245        mov r4=b0
 246        ;;
 247        st8 [in0]=r12, 8                // r12
 248        st8 [loc1]=r4, 8                // ip
 249        mov r5=loc0
 250        ;;
 251        st8 [in0]=r13, 8                // r13
 252        extr.u r5=r5, 0, 38             // ar.pfs.pfm
 253        mov r4=r0                       // user mask
 254        ;;
 255        st8 [in0]=r14, 8                // r14
 256        st8 [loc1]=r5, 8                // cfm
 257        ;;
 258        st8 [in0]=r15, 8                // r15
 259        st8 [loc1]=r4, 8                // user mask
 260        mov r5=ar.rsc
 261        ;;
 262        st8 [in0]=r16, 8                // r16
 263        st8 [loc1]=r5, 8                // ar.rsc
 264        mov r4=ar.bsp
 265        ;;
 266        st8 [in0]=r17, 8                // r17
 267        st8 [loc1]=r4, 8                // ar.bsp
 268        mov r5=ar.bspstore
 269        ;;
 270        st8 [in0]=r18, 8                // r18
 271        st8 [loc1]=r5, 8                // ar.bspstore
 272        mov r4=ar.rnat
 273        ;;
 274        st8 [in0]=r19, 8                // r19
 275        st8 [loc1]=r4, 8                // ar.rnat
 276        mov r5=ar.ccv
 277        ;;
 278        st8 [in0]=r20, 8                // r20
 279        st8 [loc1]=r5, 8                // ar.ccv
 280        mov r4=ar.unat
 281        ;;
 282        st8 [in0]=r21, 8                // r21
 283        st8 [loc1]=r4, 8                // ar.unat
 284        mov r5 = ar.fpsr
 285        ;;
 286        st8 [in0]=r22, 8                // r22
 287        st8 [loc1]=r5, 8                // ar.fpsr
 288        mov r4 = ar.unat
 289        ;;
 290        st8 [in0]=r23, 8                // r23
 291        st8 [loc1]=r4, 8                // unat
 292        mov r5 = ar.fpsr
 293        ;;
 294        st8 [in0]=r24, 8                // r24
 295        st8 [loc1]=r5, 8                // fpsr
 296        mov r4 = ar.pfs
 297        ;;
 298        st8 [in0]=r25, 8                // r25
 299        st8 [loc1]=r4, 8                // ar.pfs
 300        mov r5 = ar.lc
 301        ;;
 302        st8 [in0]=r26, 8                // r26
 303        st8 [loc1]=r5, 8                // ar.lc
 304        mov r4 = ar.ec
 305        ;;
 306        st8 [in0]=r27, 8                // r27
 307        st8 [loc1]=r4, 8                // ar.ec
 308        mov r5 = ar.csd
 309        ;;
 310        st8 [in0]=r28, 8                // r28
 311        st8 [loc1]=r5, 8                // ar.csd
 312        mov r4 = ar.ssd
 313        ;;
 314        st8 [in0]=r29, 8                // r29
 315        st8 [loc1]=r4, 8                // ar.ssd
 316        ;;
 317        st8 [in0]=r30, 8                // r30
 318        ;;
 319        st8 [in0]=r31, 8                // r31
 320        mov ar.pfs=loc0
 321        ;;
 322        br.ret.sptk.many rp
 323END(ia64_dump_cpu_regs)
 324
 325
 326