diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/subcore-asm.S')
| -rw-r--r-- | arch/powerpc/platforms/powernv/subcore-asm.S | 95 | 
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/subcore-asm.S b/arch/powerpc/platforms/powernv/subcore-asm.S new file mode 100644 index 00000000000..39bb24aa8f3 --- /dev/null +++ b/arch/powerpc/platforms/powernv/subcore-asm.S @@ -0,0 +1,95 @@ +/* + * Copyright 2013, Michael (Ellerman|Neuling), IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#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  | 
