root/arch/powerpc/platforms/powernv/subcore-asm.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /*
   3  * Copyright 2013, Michael (Ellerman|Neuling), IBM Corporation.
   4  */
   5 
   6 #include <asm/asm-offsets.h>
   7 #include <asm/ppc_asm.h>
   8 #include <asm/reg.h>
   9 
  10 #include "subcore.h"
  11 
  12 
  13 _GLOBAL(split_core_secondary_loop)
  14         /*
  15          * r3 = u8 *state, used throughout the routine
  16          * r4 = temp
  17          * r5 = temp
  18          * ..
  19          * r12 = MSR
  20          */
  21         mfmsr   r12
  22 
  23         /* Disable interrupts so SRR0/1 don't get trashed */
  24         li      r4,0
  25         ori     r4,r4,MSR_EE|MSR_SE|MSR_BE|MSR_RI
  26         andc    r4,r12,r4
  27         sync
  28         mtmsrd  r4
  29 
  30         /* Switch to real mode and leave interrupts off */
  31         li      r5, MSR_IR|MSR_DR
  32         andc    r5, r4, r5
  33 
  34         LOAD_REG_ADDR(r4, real_mode)
  35 
  36         mtspr   SPRN_SRR0,r4
  37         mtspr   SPRN_SRR1,r5
  38         rfid
  39         b       .       /* prevent speculative execution */
  40 
  41 real_mode:
  42         /* Grab values from unsplit SPRs */
  43         mfspr   r6,  SPRN_LDBAR
  44         mfspr   r7,  SPRN_PMMAR
  45         mfspr   r8,  SPRN_PMCR
  46         mfspr   r9,  SPRN_RPR
  47         mfspr   r10, SPRN_SDR1
  48 
  49         /* Order reading the SPRs vs telling the primary we are ready to split */
  50         sync
  51 
  52         /* Tell thread 0 we are in real mode */
  53         li      r4, SYNC_STEP_REAL_MODE
  54         stb     r4, 0(r3)
  55 
  56         li      r5, (HID0_POWER8_4LPARMODE | HID0_POWER8_2LPARMODE)@highest
  57         sldi    r5, r5, 48
  58 
  59         /* Loop until we see the split happen in HID0 */
  60 1:      mfspr   r4, SPRN_HID0
  61         and.    r4, r4, r5
  62         beq     1b
  63 
  64         /*
  65          * We only need to initialise the below regs once for each subcore,
  66          * but it's simpler and harmless to do it on each thread.
  67          */
  68 
  69         /* Make sure various SPRS have sane values */
  70         li      r4, 0
  71         mtspr   SPRN_LPID, r4
  72         mtspr   SPRN_PCR, r4
  73         mtspr   SPRN_HDEC, r4
  74 
  75         /* Restore SPR values now we are split */
  76         mtspr   SPRN_LDBAR, r6
  77         mtspr   SPRN_PMMAR, r7
  78         mtspr   SPRN_PMCR, r8
  79         mtspr   SPRN_RPR, r9
  80         mtspr   SPRN_SDR1, r10
  81 
  82         LOAD_REG_ADDR(r5, virtual_mode)
  83 
  84         /* Get out of real mode */
  85         mtspr   SPRN_SRR0,r5
  86         mtspr   SPRN_SRR1,r12
  87         rfid
  88         b       .       /* prevent speculative execution */
  89 
  90 virtual_mode:
  91         blr

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