root/arch/powerpc/purgatory/trampoline.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * kexec trampoline
   4  *
   5  * Based on code taken from kexec-tools and kexec-lite.
   6  *
   7  * Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation
   8  * Copyright (C) 2006, Mohan Kumar M, IBM Corporation
   9  * Copyright (C) 2013, Anton Blanchard, IBM Corporation
  10  */
  11 
  12 #include <asm/asm-compat.h>
  13 
  14         .machine ppc64
  15         .balign 256
  16         .globl purgatory_start
  17 purgatory_start:
  18         b       master
  19 
  20         /* ABI: possible run_at_load flag at 0x5c */
  21         .org purgatory_start + 0x5c
  22         .globl run_at_load
  23 run_at_load:
  24         .long 0
  25         .size run_at_load, . - run_at_load
  26 
  27         /* ABI: slaves start at 60 with r3=phys */
  28         .org purgatory_start + 0x60
  29 slave:
  30         b .
  31         /* ABI: end of copied region */
  32         .org purgatory_start + 0x100
  33         .size purgatory_start, . - purgatory_start
  34 
  35 /*
  36  * The above 0x100 bytes at purgatory_start are replaced with the
  37  * code from the kernel (or next stage) by setup_purgatory().
  38  */
  39 
  40 master:
  41         or      %r1,%r1,%r1     /* low priority to let other threads catchup */
  42         isync
  43         mr      %r17,%r3        /* save cpu id to r17 */
  44         mr      %r15,%r4        /* save physical address in reg15 */
  45 
  46         or      %r3,%r3,%r3     /* ok now to high priority, lets boot */
  47         lis     %r6,0x1
  48         mtctr   %r6             /* delay a bit for slaves to catch up */
  49         bdnz    .               /* before we overwrite 0-100 again */
  50 
  51         bl      0f              /* Work out where we're running */
  52 0:      mflr    %r18
  53 
  54         /* load device-tree address */
  55         ld      %r3, (dt_offset - 0b)(%r18)
  56         mr      %r16,%r3        /* save dt address in reg16 */
  57         li      %r4,20
  58         LWZX_BE %r6,%r3,%r4     /* fetch __be32 version number at byte 20 */
  59         cmpwi   %cr0,%r6,2      /* v2 or later? */
  60         blt     1f
  61         li      %r4,28
  62         STWX_BE %r17,%r3,%r4    /* Store my cpu as __be32 at byte 28 */
  63 1:
  64         /* load the kernel address */
  65         ld      %r4,(kernel - 0b)(%r18)
  66 
  67         /* load the run_at_load flag */
  68         /* possibly patched by kexec */
  69         ld      %r6,(run_at_load - 0b)(%r18)
  70         /* and patch it into the kernel */
  71         stw     %r6,(0x5c)(%r4)
  72 
  73         mr      %r3,%r16        /* restore dt address */
  74 
  75         li      %r5,0           /* r5 will be 0 for kernel */
  76 
  77         mfmsr   %r11
  78         andi.   %r10,%r11,1     /* test MSR_LE */
  79         bne     .Little_endian
  80 
  81         mtctr   %r4             /* prepare branch to */
  82         bctr                    /* start kernel */
  83 
  84 .Little_endian:
  85         mtsrr0  %r4             /* prepare branch to */
  86 
  87         clrrdi  %r11,%r11,1     /* clear MSR_LE */
  88         mtsrr1  %r11
  89 
  90         rfid                    /* update MSR and start kernel */
  91 
  92 
  93         .balign 8
  94         .globl kernel
  95 kernel:
  96         .8byte  0x0
  97         .size kernel, . - kernel
  98 
  99         .balign 8
 100         .globl dt_offset
 101 dt_offset:
 102         .8byte  0x0
 103         .size dt_offset, . - dt_offset
 104 
 105 
 106         .data
 107         .balign 8
 108 .globl purgatory_sha256_digest
 109 purgatory_sha256_digest:
 110         .skip   32
 111         .size purgatory_sha256_digest, . - purgatory_sha256_digest
 112 
 113         .balign 8
 114 .globl purgatory_sha_regions
 115 purgatory_sha_regions:
 116         .skip   8 * 2 * 16
 117         .size purgatory_sha_regions, . - purgatory_sha_regions

/* [<][>][^][v][top][bottom][index][help] */