Back to home page

LXR

 
 

    


0001 /*
0002  * kexec trampoline
0003  *
0004  * Based on code taken from kexec-tools and kexec-lite.
0005  *
0006  * Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation
0007  * Copyright (C) 2006, Mohan Kumar M, IBM Corporation
0008  * Copyright (C) 2013, Anton Blanchard, IBM Corporation
0009  *
0010  * This program is free software; you can redistribute it and/or modify it under
0011  * the terms of the GNU General Public License as published by the Free
0012  * Software Foundation (version 2 of the License).
0013  */
0014 
0015 #if defined(__LITTLE_ENDIAN__)
0016 #define STWX_BE stwbrx
0017 #define LWZX_BE lwbrx
0018 #elif defined(__BIG_ENDIAN__)
0019 #define STWX_BE stwx
0020 #define LWZX_BE lwzx
0021 #else
0022 #error no endianness defined!
0023 #endif
0024 
0025     .machine ppc64
0026     .balign 256
0027     .globl purgatory_start
0028 purgatory_start:
0029     b   master
0030 
0031     /* ABI: possible run_at_load flag at 0x5c */
0032     .org purgatory_start + 0x5c
0033     .globl run_at_load
0034 run_at_load:
0035     .long 0
0036     .size run_at_load, . - run_at_load
0037 
0038     /* ABI: slaves start at 60 with r3=phys */
0039     .org purgatory_start + 0x60
0040 slave:
0041     b .
0042     /* ABI: end of copied region */
0043     .org purgatory_start + 0x100
0044     .size purgatory_start, . - purgatory_start
0045 
0046 /*
0047  * The above 0x100 bytes at purgatory_start are replaced with the
0048  * code from the kernel (or next stage) by setup_purgatory().
0049  */
0050 
0051 master:
0052     or  %r1,%r1,%r1 /* low priority to let other threads catchup */
0053     isync
0054     mr  %r17,%r3    /* save cpu id to r17 */
0055     mr  %r15,%r4    /* save physical address in reg15 */
0056 
0057     or  %r3,%r3,%r3 /* ok now to high priority, lets boot */
0058     lis %r6,0x1
0059     mtctr   %r6     /* delay a bit for slaves to catch up */
0060     bdnz    .       /* before we overwrite 0-100 again */
0061 
0062     bl  0f      /* Work out where we're running */
0063 0:  mflr    %r18
0064 
0065     /* load device-tree address */
0066     ld  %r3, (dt_offset - 0b)(%r18)
0067     mr  %r16,%r3    /* save dt address in reg16 */
0068     li  %r4,20
0069     LWZX_BE %r6,%r3,%r4 /* fetch __be32 version number at byte 20 */
0070     cmpwi   %r0,%r6,2   /* v2 or later? */
0071     blt 1f
0072     li  %r4,28
0073     STWX_BE %r17,%r3,%r4    /* Store my cpu as __be32 at byte 28 */
0074 1:
0075     /* load the kernel address */
0076     ld  %r4,(kernel - 0b)(%r18)
0077 
0078     /* load the run_at_load flag */
0079     /* possibly patched by kexec */
0080     ld  %r6,(run_at_load - 0b)(%r18)
0081     /* and patch it into the kernel */
0082     stw %r6,(0x5c)(%r4)
0083 
0084     mr  %r3,%r16    /* restore dt address */
0085 
0086     li  %r5,0       /* r5 will be 0 for kernel */
0087 
0088     mfmsr   %r11
0089     andi.   %r10,%r11,1 /* test MSR_LE */
0090     bne .Little_endian
0091 
0092     mtctr   %r4     /* prepare branch to */
0093     bctr            /* start kernel */
0094 
0095 .Little_endian:
0096     mtsrr0  %r4     /* prepare branch to */
0097 
0098     clrrdi  %r11,%r11,1 /* clear MSR_LE */
0099     mtsrr1  %r11
0100 
0101     rfid            /* update MSR and start kernel */
0102 
0103 
0104     .balign 8
0105     .globl kernel
0106 kernel:
0107     .llong  0x0
0108     .size kernel, . - kernel
0109 
0110     .balign 8
0111     .globl dt_offset
0112 dt_offset:
0113     .llong  0x0
0114     .size dt_offset, . - dt_offset
0115 
0116 
0117     .data
0118     .balign 8
0119 .globl sha256_digest
0120 sha256_digest:
0121     .skip   32
0122     .size sha256_digest, . - sha256_digest
0123 
0124     .balign 8
0125 .globl sha_regions
0126 sha_regions:
0127     .skip   8 * 2 * 16
0128     .size sha_regions, . - sha_regions