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