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