2019-05-27 08:55:01 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2011-01-20 18:50:55 +11:00
|
|
|
/*
|
|
|
|
* This file contains low level CPU setup functions.
|
|
|
|
* Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <asm/processor.h>
|
|
|
|
#include <asm/page.h>
|
|
|
|
#include <asm/cputable.h>
|
|
|
|
#include <asm/ppc_asm.h>
|
|
|
|
#include <asm/asm-offsets.h>
|
|
|
|
#include <asm/cache.h>
|
2016-03-01 12:59:20 +05:30
|
|
|
#include <asm/book3s/64/mmu-hash.h>
|
2011-01-20 18:50:55 +11:00
|
|
|
|
|
|
|
/* Entry: r3 = crap, r4 = ptr to cputable entry
|
|
|
|
*
|
|
|
|
* Note that we can be called twice for pseudo-PVRs
|
|
|
|
*/
|
|
|
|
_GLOBAL(__setup_cpu_power7)
|
|
|
|
mflr r11
|
|
|
|
bl __init_hvmode_206
|
|
|
|
mtlr r11
|
|
|
|
beqlr
|
2011-03-01 15:46:09 +11:00
|
|
|
li r0,0
|
|
|
|
mtspr SPRN_LPID,r0
|
2019-09-17 10:46:05 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r0, PCR_MASK)
|
2018-05-18 11:37:42 +10:00
|
|
|
mtspr SPRN_PCR,r0
|
2012-11-05 14:40:18 +11:00
|
|
|
mfspr r3,SPRN_LPCR
|
2017-04-05 17:54:55 +10:00
|
|
|
li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
|
2017-04-19 05:12:17 +10:00
|
|
|
bl __init_LPCR_ISA206
|
2011-01-20 18:50:55 +11:00
|
|
|
mtlr r11
|
|
|
|
blr
|
|
|
|
|
|
|
|
_GLOBAL(__restore_cpu_power7)
|
|
|
|
mflr r11
|
|
|
|
mfmsr r3
|
|
|
|
rldicl. r0,r3,4,63
|
|
|
|
beqlr
|
2011-03-01 15:46:09 +11:00
|
|
|
li r0,0
|
|
|
|
mtspr SPRN_LPID,r0
|
2019-09-17 10:46:05 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r0, PCR_MASK)
|
2018-05-18 11:37:42 +10:00
|
|
|
mtspr SPRN_PCR,r0
|
2012-11-05 14:40:18 +11:00
|
|
|
mfspr r3,SPRN_LPCR
|
2017-04-05 17:54:55 +10:00
|
|
|
li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
|
2017-04-19 05:12:17 +10:00
|
|
|
bl __init_LPCR_ISA206
|
2012-10-30 19:34:14 +00:00
|
|
|
mtlr r11
|
|
|
|
blr
|
|
|
|
|
|
|
|
_GLOBAL(__setup_cpu_power8)
|
|
|
|
mflr r11
|
2013-03-04 19:45:50 +00:00
|
|
|
bl __init_FSCR
|
2013-04-25 19:28:22 +00:00
|
|
|
bl __init_PMU
|
2016-06-26 23:07:06 +05:30
|
|
|
bl __init_PMU_ISA207
|
2012-10-30 19:34:14 +00:00
|
|
|
bl __init_hvmode_206
|
|
|
|
mtlr r11
|
|
|
|
beqlr
|
|
|
|
li r0,0
|
|
|
|
mtspr SPRN_LPID,r0
|
2019-09-17 10:46:05 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r0, PCR_MASK)
|
2018-05-18 11:37:42 +10:00
|
|
|
mtspr SPRN_PCR,r0
|
2012-11-05 14:40:18 +11:00
|
|
|
mfspr r3,SPRN_LPCR
|
2014-06-11 15:59:28 +10:00
|
|
|
ori r3, r3, LPCR_PECEDH
|
2017-04-05 17:54:55 +10:00
|
|
|
li r4,0 /* LPES = 0 */
|
2017-04-19 05:12:17 +10:00
|
|
|
bl __init_LPCR_ISA206
|
2013-03-05 17:35:24 +00:00
|
|
|
bl __init_HFSCR
|
2013-04-25 19:28:22 +00:00
|
|
|
bl __init_PMU_HV
|
2016-06-26 23:07:06 +05:30
|
|
|
bl __init_PMU_HV_ISA207
|
2012-10-30 19:34:14 +00:00
|
|
|
mtlr r11
|
|
|
|
blr
|
|
|
|
|
|
|
|
_GLOBAL(__restore_cpu_power8)
|
|
|
|
mflr r11
|
2013-03-04 19:45:50 +00:00
|
|
|
bl __init_FSCR
|
2013-04-25 19:28:22 +00:00
|
|
|
bl __init_PMU
|
2016-06-26 23:07:06 +05:30
|
|
|
bl __init_PMU_ISA207
|
2012-10-30 19:34:14 +00:00
|
|
|
mfmsr r3
|
|
|
|
rldicl. r0,r3,4,63
|
2013-04-24 21:00:37 +00:00
|
|
|
mtlr r11
|
2012-10-30 19:34:14 +00:00
|
|
|
beqlr
|
|
|
|
li r0,0
|
|
|
|
mtspr SPRN_LPID,r0
|
2019-09-17 10:46:05 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r0, PCR_MASK)
|
2018-05-18 11:37:42 +10:00
|
|
|
mtspr SPRN_PCR,r0
|
2012-11-05 14:40:18 +11:00
|
|
|
mfspr r3,SPRN_LPCR
|
2014-06-11 15:59:28 +10:00
|
|
|
ori r3, r3, LPCR_PECEDH
|
2017-04-05 17:54:55 +10:00
|
|
|
li r4,0 /* LPES = 0 */
|
2017-04-19 05:12:17 +10:00
|
|
|
bl __init_LPCR_ISA206
|
2013-03-05 17:35:24 +00:00
|
|
|
bl __init_HFSCR
|
2013-04-25 19:28:22 +00:00
|
|
|
bl __init_PMU_HV
|
2016-06-26 23:07:06 +05:30
|
|
|
bl __init_PMU_HV_ISA207
|
2011-01-20 18:50:55 +11:00
|
|
|
mtlr r11
|
|
|
|
blr
|
|
|
|
|
2020-05-21 11:43:41 +10:00
|
|
|
_GLOBAL(__setup_cpu_power10)
|
|
|
|
mflr r11
|
|
|
|
bl __init_FSCR_power10
|
2020-07-23 03:32:37 -04:00
|
|
|
bl __init_PMU
|
|
|
|
bl __init_PMU_ISA31
|
2020-05-21 11:43:41 +10:00
|
|
|
b 1f
|
|
|
|
|
2016-02-19 11:16:24 +11:00
|
|
|
_GLOBAL(__setup_cpu_power9)
|
|
|
|
mflr r11
|
2020-06-11 18:12:03 +10:00
|
|
|
bl __init_FSCR_power9
|
2020-07-23 03:32:37 -04:00
|
|
|
bl __init_PMU
|
|
|
|
1: bl __init_hvmode_206
|
2016-02-19 11:16:24 +11:00
|
|
|
mtlr r11
|
|
|
|
beqlr
|
|
|
|
li r0,0
|
2016-11-22 23:36:40 +05:30
|
|
|
mtspr SPRN_PSSCR,r0
|
2016-02-19 11:16:24 +11:00
|
|
|
mtspr SPRN_LPID,r0
|
2017-12-06 18:21:14 +10:00
|
|
|
mtspr SPRN_PID,r0
|
2019-09-17 10:46:05 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r0, PCR_MASK)
|
2018-05-18 11:37:42 +10:00
|
|
|
mtspr SPRN_PCR,r0
|
2016-02-19 11:16:24 +11:00
|
|
|
mfspr r3,SPRN_LPCR
|
2017-04-05 17:54:55 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
|
2016-11-21 18:08:05 +11:00
|
|
|
or r3, r3, r4
|
2017-02-22 10:42:02 +05:30
|
|
|
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
|
|
|
|
andc r3, r3, r4
|
2017-04-19 05:12:16 +10:00
|
|
|
li r4,0 /* LPES = 0 */
|
2017-04-19 05:12:17 +10:00
|
|
|
bl __init_LPCR_ISA300
|
2016-02-19 11:16:24 +11:00
|
|
|
bl __init_HFSCR
|
2016-06-26 23:07:06 +05:30
|
|
|
bl __init_PMU_HV
|
2016-02-19 11:16:24 +11:00
|
|
|
mtlr r11
|
|
|
|
blr
|
|
|
|
|
2020-05-21 11:43:41 +10:00
|
|
|
_GLOBAL(__restore_cpu_power10)
|
|
|
|
mflr r11
|
|
|
|
bl __init_FSCR_power10
|
2020-07-23 03:32:37 -04:00
|
|
|
bl __init_PMU
|
|
|
|
bl __init_PMU_ISA31
|
2020-05-21 11:43:41 +10:00
|
|
|
b 1f
|
|
|
|
|
2016-02-19 11:16:24 +11:00
|
|
|
_GLOBAL(__restore_cpu_power9)
|
|
|
|
mflr r11
|
2020-06-11 18:12:03 +10:00
|
|
|
bl __init_FSCR_power9
|
2020-07-23 03:32:37 -04:00
|
|
|
bl __init_PMU
|
|
|
|
1: mfmsr r3
|
2016-02-19 11:16:24 +11:00
|
|
|
rldicl. r0,r3,4,63
|
|
|
|
mtlr r11
|
|
|
|
beqlr
|
|
|
|
li r0,0
|
2016-11-22 23:36:40 +05:30
|
|
|
mtspr SPRN_PSSCR,r0
|
2016-02-19 11:16:24 +11:00
|
|
|
mtspr SPRN_LPID,r0
|
2017-12-06 18:21:14 +10:00
|
|
|
mtspr SPRN_PID,r0
|
2019-09-17 10:46:05 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r0, PCR_MASK)
|
2018-05-18 11:37:42 +10:00
|
|
|
mtspr SPRN_PCR,r0
|
2016-02-19 11:16:24 +11:00
|
|
|
mfspr r3,SPRN_LPCR
|
2017-04-05 17:54:55 +10:00
|
|
|
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
|
2016-11-21 18:08:05 +11:00
|
|
|
or r3, r3, r4
|
2017-02-22 10:42:02 +05:30
|
|
|
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
|
|
|
|
andc r3, r3, r4
|
2017-04-19 05:12:16 +10:00
|
|
|
li r4,0 /* LPES = 0 */
|
2017-04-19 05:12:17 +10:00
|
|
|
bl __init_LPCR_ISA300
|
2016-02-19 11:16:24 +11:00
|
|
|
bl __init_HFSCR
|
2016-06-26 23:07:06 +05:30
|
|
|
bl __init_PMU_HV
|
2016-02-19 11:16:24 +11:00
|
|
|
mtlr r11
|
|
|
|
blr
|
|
|
|
|
2011-01-20 18:50:55 +11:00
|
|
|
__init_hvmode_206:
|
powerpc, KVM: Split HVMODE_206 cpu feature bit into separate HV and architecture bits
This replaces the single CPU_FTR_HVMODE_206 bit with two bits, one to
indicate that we have a usable hypervisor mode, and another to indicate
that the processor conforms to PowerISA version 2.06. We also add
another bit to indicate that the processor conforms to ISA version 2.01
and set that for PPC970 and derivatives.
Some PPC970 chips (specifically those in Apple machines) have a
hypervisor mode in that MSR[HV] is always 1, but the hypervisor mode
is not useful in the sense that there is no way to run any code in
supervisor mode (HV=0 PR=0). On these processors, the LPES0 and LPES1
bits in HID4 are always 0, and we use that as a way of detecting that
hypervisor mode is not useful.
Where we have a feature section in assembly code around code that
only applies on POWER7 in hypervisor mode, we use a construct like
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
The definition of END_FTR_SECTION_IFSET is such that the code will
be enabled (not overwritten with nops) only if all bits in the
provided mask are set.
Note that the CPU feature check in __tlbie() only needs to check the
ARCH_206 bit, not the HVMODE bit, because __tlbie() can only get called
if we are running bare-metal, i.e. in hypervisor mode.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2011-06-29 00:26:11 +00:00
|
|
|
/* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */
|
2011-01-20 18:50:55 +11:00
|
|
|
mfmsr r3
|
|
|
|
rldicl. r0,r3,4,63
|
|
|
|
bnelr
|
|
|
|
ld r5,CPU_SPEC_FEATURES(r4)
|
2018-10-08 16:30:47 +11:00
|
|
|
LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE | CPU_FTR_P9_TM_HV_ASSIST)
|
|
|
|
andc r5,r5,r6
|
2011-01-20 18:50:55 +11:00
|
|
|
std r5,CPU_SPEC_FEATURES(r4)
|
|
|
|
blr
|
|
|
|
|
2017-04-19 05:12:17 +10:00
|
|
|
__init_LPCR_ISA206:
|
2011-01-20 18:50:55 +11:00
|
|
|
/* Setup a sane LPCR:
|
2017-04-05 17:54:55 +10:00
|
|
|
* Called with initial LPCR in R3 and desired LPES 2-bit value in R4
|
2011-01-20 18:50:55 +11:00
|
|
|
*
|
2011-04-05 14:20:31 +10:00
|
|
|
* LPES = 0b01 (HSRR0/1 used for 0x500)
|
2011-01-20 18:50:55 +11:00
|
|
|
* PECE = 0b111
|
2011-01-24 13:25:55 +11:00
|
|
|
* DPFD = 4
|
2011-06-29 00:20:24 +00:00
|
|
|
* HDICE = 0
|
|
|
|
* VC = 0b100 (VPM0=1, VPM1=0, ISL=0)
|
|
|
|
* VRMASD = 0b10000 (L=1, LP=00)
|
2011-01-20 18:50:55 +11:00
|
|
|
*
|
|
|
|
* Other bits untouched for now
|
|
|
|
*/
|
2017-04-19 05:12:17 +10:00
|
|
|
li r5,0x10
|
|
|
|
rldimi r3,r5, LPCR_VRMASD_SH, 64-LPCR_VRMASD_SH-5
|
|
|
|
|
|
|
|
/* POWER9 has no VRMASD */
|
|
|
|
__init_LPCR_ISA300:
|
2017-04-05 17:54:55 +10:00
|
|
|
rldimi r3,r4, LPCR_LPES_SH, 64-LPCR_LPES_SH-2
|
2011-01-20 18:50:55 +11:00
|
|
|
ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
|
2011-01-24 13:25:55 +11:00
|
|
|
li r5,4
|
2011-06-29 00:20:24 +00:00
|
|
|
rldimi r3,r5, LPCR_DPFD_SH, 64-LPCR_DPFD_SH-3
|
|
|
|
clrrdi r3,r3,1 /* clear HDICE */
|
|
|
|
li r5,4
|
|
|
|
rldimi r3,r5, LPCR_VC_SH, 0
|
2011-01-20 18:50:55 +11:00
|
|
|
mtspr SPRN_LPCR,r3
|
|
|
|
isync
|
|
|
|
blr
|
2011-03-01 15:46:09 +11:00
|
|
|
|
2020-05-21 11:43:41 +10:00
|
|
|
__init_FSCR_power10:
|
|
|
|
mfspr r3, SPRN_FSCR
|
|
|
|
ori r3, r3, FSCR_PREFIX
|
|
|
|
mtspr SPRN_FSCR, r3
|
|
|
|
// fall through
|
|
|
|
|
2020-06-11 18:12:03 +10:00
|
|
|
__init_FSCR_power9:
|
|
|
|
mfspr r3, SPRN_FSCR
|
|
|
|
ori r3, r3, FSCR_SCV
|
|
|
|
mtspr SPRN_FSCR, r3
|
|
|
|
// fall through
|
|
|
|
|
2013-02-07 15:46:58 +00:00
|
|
|
__init_FSCR:
|
|
|
|
mfspr r3,SPRN_FSCR
|
powerpc/64s: Don't init FSCR_DSCR in __init_FSCR()
__init_FSCR() was added originally in commit 2468dcf641e4 ("powerpc:
Add support for context switching the TAR register") (Feb 2013), and
only set FSCR_TAR.
At that point FSCR (Facility Status and Control Register) was not
context switched, so the setting was permanent after boot.
Later we added initialisation of FSCR_DSCR to __init_FSCR(), in commit
54c9b2253d34 ("powerpc: Set DSCR bit in FSCR setup") (Mar 2013), again
that was permanent after boot.
Then commit 2517617e0de6 ("powerpc: Fix context switch DSCR on
POWER8") (Aug 2013) added a limited context switch of FSCR, just the
FSCR_DSCR bit was context switched based on thread.dscr_inherit. That
commit said "This clears the H/FSCR DSCR bit initially", but it
didn't, it left the initialisation of FSCR_DSCR in __init_FSCR().
However the initial context switch from init_task to pid 1 would clear
FSCR_DSCR because thread.dscr_inherit was 0.
That commit also introduced the requirement that FSCR_DSCR be clear
for user processes, so that we can take the facility unavailable
interrupt in order to manage dscr_inherit.
Then in commit 152d523e6307 ("powerpc: Create context switch helpers
save_sprs() and restore_sprs()") (Dec 2015) FSCR was added to
thread_struct. However it still wasn't fully context switched, we just
took the existing value and set FSCR_DSCR if the new thread had
dscr_inherit set. FSCR was still initialised at boot to FSCR_DSCR |
FSCR_TAR, but that value was not propagated into the thread_struct, so
the initial context switch set FSCR_DSCR back to 0.
Finally commit b57bd2de8c6c ("powerpc: Improve FSCR init and context
switching") (Jun 2016) added a full context switch of the FSCR, and
added an initialisation of init_task.thread.fscr to FSCR_TAR |
FSCR_EBB, but omitted FSCR_DSCR.
The end result is that swapper runs with FSCR_DSCR set because of the
initialisation in __init_FSCR(), but no other processes do, they use
the value from init_task.thread.fscr.
Having FSCR_DSCR set for swapper allows it to access SPR 3 from
userspace, but swapper never runs userspace, so it has no useful
effect. It's also confusing to have the value initialised in two
places to two different values.
So remove FSCR_DSCR from __init_FSCR(), this at least gets us to the
point where there's a single value of FSCR, even if it's still set in
two places.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Tested-by: Alistair Popple <alistair@popple.id.au>
Link: https://lore.kernel.org/r/20200527145843.2761782-1-mpe@ellerman.id.au
2020-05-28 00:58:40 +10:00
|
|
|
ori r3,r3,FSCR_TAR|FSCR_EBB
|
2013-02-07 15:46:58 +00:00
|
|
|
mtspr SPRN_FSCR,r3
|
|
|
|
blr
|
|
|
|
|
2013-03-05 17:35:24 +00:00
|
|
|
__init_HFSCR:
|
|
|
|
mfspr r3,SPRN_HFSCR
|
2013-04-25 20:54:55 +00:00
|
|
|
ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\
|
2016-11-23 10:44:09 +11:00
|
|
|
HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP
|
2013-03-05 17:35:24 +00:00
|
|
|
mtspr SPRN_HFSCR,r3
|
|
|
|
blr
|
|
|
|
|
2013-04-25 19:28:22 +00:00
|
|
|
__init_PMU_HV:
|
|
|
|
li r5,0
|
|
|
|
mtspr SPRN_MMCRC,r5
|
2016-06-26 23:07:06 +05:30
|
|
|
blr
|
|
|
|
|
|
|
|
__init_PMU_HV_ISA207:
|
|
|
|
li r5,0
|
2013-04-25 19:28:22 +00:00
|
|
|
mtspr SPRN_MMCRH,r5
|
|
|
|
blr
|
|
|
|
|
|
|
|
__init_PMU:
|
|
|
|
li r5,0
|
|
|
|
mtspr SPRN_MMCRA,r5
|
|
|
|
mtspr SPRN_MMCR0,r5
|
|
|
|
mtspr SPRN_MMCR1,r5
|
|
|
|
mtspr SPRN_MMCR2,r5
|
|
|
|
blr
|
2016-06-26 23:07:06 +05:30
|
|
|
|
|
|
|
__init_PMU_ISA207:
|
|
|
|
li r5,0
|
|
|
|
mtspr SPRN_MMCRS,r5
|
|
|
|
blr
|
2020-07-23 03:32:37 -04:00
|
|
|
|
|
|
|
__init_PMU_ISA31:
|
|
|
|
li r5,0
|
|
|
|
mtspr SPRN_MMCR3,r5
|
|
|
|
LOAD_REG_IMMEDIATE(r5, MMCRA_BHRB_DISABLE)
|
|
|
|
mtspr SPRN_MMCRA,r5
|
|
|
|
blr
|