linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc: add denormalisation exception handling for POWER6/7
@ 2011-07-11  5:52 Michael Neuling
  2011-07-12  3:51 ` Kumar Gala
  2011-07-13  5:27 ` Kumar Gala
  0 siblings, 2 replies; 9+ messages in thread
From: Michael Neuling @ 2011-07-11  5:52 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, miltonm

On POWER6 and POWER7 if the input operand to an instruction is a
denormalised single precision binary floating we can take a
denormalisation exception where it's expected that the hypervisor (HV=1)
will fix up the inputs before the instruction is run.

This adds code to handle this denormalisation exception for POWER6 and
POWER7.

It also add a CONFIG_PPC_DENORMALISATION option and sets it in
pseries/ppc64_defconfig. 

This is useful on bare metal systems only.  Based on patch from Milton
Miller.

Signed-off-by: Michael Neuling <mikey@neuling.org>

---
 arch/powerpc/Kconfig                   |    7 +
 arch/powerpc/configs/ppc64_defconfig   |    1 
 arch/powerpc/configs/pseries_defconfig |    1 
 arch/powerpc/include/asm/ppc-opcode.h  |    2 
 arch/powerpc/include/asm/reg.h         |    1 
 arch/powerpc/kernel/exceptions-64s.S   |  125 +++++++++++++++++++++++++++++++++
 6 files changed, 137 insertions(+)

Index: linux-ozlabs/arch/powerpc/Kconfig
===================================================================
--- linux-ozlabs.orig/arch/powerpc/Kconfig
+++ linux-ozlabs/arch/powerpc/Kconfig
@@ -556,6 +556,13 @@ config SCHED_SMT
 	  when dealing with POWER5 cpus at a cost of slightly increased
 	  overhead in some places. If unsure say N here.
 
+config PPC_DENORMALISATION
+	bool "PowerPC denormalisation exception handling"
+	default "n"
+	---help---
+	  Add support for handling denormalisation of single precision
+	  values.  Useful for bare metal only.  If unsure say Y here.
+
 config CMDLINE_BOOL
 	bool "Default bootloader kernel arguments"
 
Index: linux-ozlabs/arch/powerpc/configs/ppc64_defconfig
===================================================================
--- linux-ozlabs.orig/arch/powerpc/configs/ppc64_defconfig
+++ linux-ozlabs/arch/powerpc/configs/ppc64_defconfig
@@ -54,6 +54,7 @@ CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
 CONFIG_PCCARD=y
 CONFIG_ELECTRA_CF=y
 CONFIG_HOTPLUG_PCI=m
Index: linux-ozlabs/arch/powerpc/configs/pseries_defconfig
===================================================================
--- linux-ozlabs.orig/arch/powerpc/configs/pseries_defconfig
+++ linux-ozlabs/arch/powerpc/configs/pseries_defconfig
@@ -47,6 +47,7 @@ CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PPC_64K_PAGES=y
 CONFIG_PPC_SUBPAGE_PROT=y
 CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
 CONFIG_HOTPLUG_PCI=m
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
Index: linux-ozlabs/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- linux-ozlabs.orig/arch/powerpc/include/asm/ppc-opcode.h
+++ linux-ozlabs/arch/powerpc/include/asm/ppc-opcode.h
@@ -157,6 +157,8 @@
 					       VSX_XX1((s), (a), (b)))
 #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
 					       VSX_XX3((t), (a), (b)))
+#define XVCPSGNDP(t, a, b)	stringify_in_c(.long (0xf0000780 | \
+					       VSX_XX3((t), (a), (b))))
 
 #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
 #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
Index: linux-ozlabs/arch/powerpc/include/asm/reg.h
===================================================================
--- linux-ozlabs.orig/arch/powerpc/include/asm/reg.h
+++ linux-ozlabs/arch/powerpc/include/asm/reg.h
@@ -496,6 +496,7 @@
 
 #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
 #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
+#define   HSRR1_DENORM		0x00100000 /* Denorm exception */
 
 #define SPRN_TBCTL	0x35f	/* PA6T Timebase control register */
 #define   TBCTL_FREEZE		0x0000000000000000ull /* Freeze all tbs */
Index: linux-ozlabs/arch/powerpc/kernel/exceptions-64s.S
===================================================================
--- linux-ozlabs.orig/arch/powerpc/kernel/exceptions-64s.S
+++ linux-ozlabs/arch/powerpc/kernel/exceptions-64s.S
@@ -264,6 +264,31 @@ vsx_unavailable_pSeries_1:
 	STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
 #endif /* CONFIG_CBE_RAS */
 	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
+
+#ifdef CONFIG_PPC_DENORMALISATION
+	. = 0x1500
+	.global denorm_Hypervisor
+denorm_Hypervisor:
+	HMT_MEDIUM
+	mtspr	SPRN_SPRG_HSCRATCH0,r13
+	mfspr	r13,SPRN_SPRG_HPACA
+	std	r9,PACA_EXGEN+EX_R9(r13)
+	std	r10,PACA_EXGEN+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R11(r13)
+	std	r12,PACA_EXGEN+EX_R12(r13)
+	mfspr	r9,SPRN_SPRG_HSCRATCH0
+	std	r9,PACA_EXGEN+EX_R13(r13)
+	mfcr	r9
+
+	mfspr	r10,SPRN_HSRR1
+	mfspr	r11,SPRN_HSRR0		/* save HSRR0 */
+	andis.	r10,r10,(HSRR1_DENORM)@h /* denorm? */
+	addi	r11,r11,-4		/* HSRR0 is next instruction */
+	bne+	denorm_assist
+
+	EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
+#endif
+
 #ifdef CONFIG_CBE_RAS
 	STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
 #endif /* CONFIG_CBE_RAS */
@@ -317,6 +342,103 @@ masked_Hinterrupt:
 	hrfid
 	b	.
 
+#ifdef CONFIG_PPC_DENORMALISATION
+denorm_assist:
+BEGIN_FTR_SECTION
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER6 do that here for all FP regs.
+ */
+	mfmsr	r10
+	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
+	xori	r10,r10,(MSR_FE0|MSR_FE1)
+	mtmsrd	r10
+	sync
+	fmr	0,0
+	fmr	1,1
+	fmr	2,2
+	fmr	3,3
+	fmr	4,4
+	fmr	5,5
+	fmr	6,6
+	fmr	7,7
+	fmr	8,8
+	fmr	9,9
+	fmr	10,10
+	fmr	11,11
+	fmr	12,12
+	fmr	13,13
+	fmr	14,14
+	fmr	15,15
+	fmr	16,16
+	fmr	17,17
+	fmr	18,18
+	fmr	19,19
+	fmr	20,20
+	fmr	21,21
+	fmr	22,22
+	fmr	23,23
+	fmr	24,24
+	fmr	25,25
+	fmr	26,26
+	fmr	27,27
+	fmr	28,28
+	fmr	29,29
+	fmr	30,30
+	fmr	31,31
+FTR_SECTION_ELSE
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER7 do that here for the first 32 VSX registers only.
+ */
+	mfmsr	r10
+	oris	r10,r10,MSR_VSX@h
+	mtmsrd	r10
+	sync
+	XVCPSGNDP(0,0,0)
+	XVCPSGNDP(1,1,1)
+	XVCPSGNDP(2,2,2)
+	XVCPSGNDP(3,3,3)
+	XVCPSGNDP(4,4,4)
+	XVCPSGNDP(5,5,5)
+	XVCPSGNDP(6,6,6)
+	XVCPSGNDP(7,7,7)
+	XVCPSGNDP(8,8,8)
+	XVCPSGNDP(9,9,9)
+	XVCPSGNDP(10,10,10)
+	XVCPSGNDP(11,11,11)
+	XVCPSGNDP(12,12,12)
+	XVCPSGNDP(13,13,13)
+	XVCPSGNDP(14,14,14)
+	XVCPSGNDP(15,15,15)
+	XVCPSGNDP(16,16,16)
+	XVCPSGNDP(17,17,17)
+	XVCPSGNDP(18,18,18)
+	XVCPSGNDP(19,19,19)
+	XVCPSGNDP(20,20,20)
+	XVCPSGNDP(21,21,21)
+	XVCPSGNDP(22,22,22)
+	XVCPSGNDP(23,23,23)
+	XVCPSGNDP(24,24,24)
+	XVCPSGNDP(25,25,25)
+	XVCPSGNDP(26,26,26)
+	XVCPSGNDP(27,27,27)
+	XVCPSGNDP(28,28,28)
+	XVCPSGNDP(29,29,29)
+	XVCPSGNDP(30,30,30)
+	XVCPSGNDP(31,31,31)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206)
+	mtspr	SPRN_HSRR0,r11
+	mtcrf	0x80,r9
+	ld	r9,PACA_EXGEN+EX_R9(r13)
+	ld	r10,PACA_EXGEN+EX_R10(r13)
+	ld	r11,PACA_EXGEN+EX_R11(r13)
+	ld	r12,PACA_EXGEN+EX_R12(r13)
+	ld	r13,PACA_EXGEN+EX_R13(r13)
+	HRFID
+	b	.
+#endif
+
 	.align	7
 do_stab_bolted_pSeries:
 	std	r11,PACA_EXSLB+EX_R11(r13)
@@ -419,6 +541,9 @@ machine_check_common:
         STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 	STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+#ifdef CONFIG_PPC_DENORMALISATION
+	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
+#endif
 #ifdef CONFIG_ALTIVEC
 	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
 #else

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2011-07-11  5:52 [PATCH] powerpc: add denormalisation exception handling for POWER6/7 Michael Neuling
@ 2011-07-12  3:51 ` Kumar Gala
  2011-07-12  4:12   ` Benjamin Herrenschmidt
  2011-07-13  5:27 ` Kumar Gala
  1 sibling, 1 reply; 9+ messages in thread
From: Kumar Gala @ 2011-07-12  3:51 UTC (permalink / raw)
  To: Michael Neuling; +Cc: Paul Mackerras, miltonm, linuxppc-dev


On Jul 11, 2011, at 12:52 AM, Michael Neuling wrote:

> On POWER6 and POWER7 if the input operand to an instruction is a
> denormalised single precision binary floating we can take a
> denormalisation exception where it's expected that the hypervisor =
(HV=3D1)
> will fix up the inputs before the instruction is run.
>=20
> This adds code to handle this denormalisation exception for POWER6 and
> POWER7.
>=20
> It also add a CONFIG_PPC_DENORMALISATION option and sets it in
> pseries/ppc64_defconfig.=20
>=20
> This is useful on bare metal systems only.  Based on patch from Milton
> Miller.
>=20
> Signed-off-by: Michael Neuling <mikey@neuling.org>
>=20
> ---
> arch/powerpc/Kconfig                   |    7 +
> arch/powerpc/configs/ppc64_defconfig   |    1=20
> arch/powerpc/configs/pseries_defconfig |    1=20
> arch/powerpc/include/asm/ppc-opcode.h  |    2=20
> arch/powerpc/include/asm/reg.h         |    1=20
> arch/powerpc/kernel/exceptions-64s.S   |  125 =
+++++++++++++++++++++++++++++++++
> 6 files changed, 137 insertions(+)

Is it possible to run POWER6/7 systems in baremetal if you are not IBM?

Just wondering if this is useful to anyone but IBM.

- k=

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2011-07-12  3:51 ` Kumar Gala
@ 2011-07-12  4:12   ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2011-07-12  4:12 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Michael Neuling, Paul Mackerras, miltonm

On Mon, 2011-07-11 at 22:51 -0500, Kumar Gala wrote:
> On Jul 11, 2011, at 12:52 AM, Michael Neuling wrote:
> 
> > On POWER6 and POWER7 if the input operand to an instruction is a
> > denormalised single precision binary floating we can take a
> > denormalisation exception where it's expected that the hypervisor (HV=1)
> > will fix up the inputs before the instruction is run.
> > 
> > This adds code to handle this denormalisation exception for POWER6 and
> > POWER7.
> > 
> > It also add a CONFIG_PPC_DENORMALISATION option and sets it in
> > pseries/ppc64_defconfig. 
> > 
> > This is useful on bare metal systems only.  Based on patch from Milton
> > Miller.
> > 
> > Signed-off-by: Michael Neuling <mikey@neuling.org>
> > 
> > ---
> > arch/powerpc/Kconfig                   |    7 +
> > arch/powerpc/configs/ppc64_defconfig   |    1 
> > arch/powerpc/configs/pseries_defconfig |    1 
> > arch/powerpc/include/asm/ppc-opcode.h  |    2 
> > arch/powerpc/include/asm/reg.h         |    1 
> > arch/powerpc/kernel/exceptions-64s.S   |  125 +++++++++++++++++++++++++++++++++
> > 6 files changed, 137 insertions(+)
> 
> Is it possible to run POWER6/7 systems in baremetal if you are not IBM?
> 
> Just wondering if this is useful to anyone but IBM.

While I cannot obviously comment on unreleased systems, the fact that
we've been contributing all sort of patches to run P7 in "HV" mode and
KVM on them should be enough of a hint :-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2011-07-11  5:52 [PATCH] powerpc: add denormalisation exception handling for POWER6/7 Michael Neuling
  2011-07-12  3:51 ` Kumar Gala
@ 2011-07-13  5:27 ` Kumar Gala
  2011-07-13  5:30   ` Michael Neuling
  2012-09-10  6:54   ` Michael Neuling
  1 sibling, 2 replies; 9+ messages in thread
From: Kumar Gala @ 2011-07-13  5:27 UTC (permalink / raw)
  To: Michael Neuling; +Cc: Paul Mackerras, miltonm, linuxppc-dev


On Jul 11, 2011, at 12:52 AM, Michael Neuling wrote:

> On POWER6 and POWER7 if the input operand to an instruction is a
> denormalised single precision binary floating we can take a
> denormalisation exception where it's expected that the hypervisor =
(HV=3D1)
> will fix up the inputs before the instruction is run.
>=20
> This adds code to handle this denormalisation exception for POWER6 and
> POWER7.
>=20
> It also add a CONFIG_PPC_DENORMALISATION option and sets it in
> pseries/ppc64_defconfig.=20
>=20
> This is useful on bare metal systems only.  Based on patch from Milton
> Miller.
>=20
> Signed-off-by: Michael Neuling <mikey@neuling.org>
>=20
> ---
> arch/powerpc/Kconfig                   |    7 +
> arch/powerpc/configs/ppc64_defconfig   |    1=20
> arch/powerpc/configs/pseries_defconfig |    1=20
> arch/powerpc/include/asm/ppc-opcode.h  |    2=20
> arch/powerpc/include/asm/reg.h         |    1=20
> arch/powerpc/kernel/exceptions-64s.S   |  125 =
+++++++++++++++++++++++++++++++++
> 6 files changed, 137 insertions(+)
>=20
> Index: linux-ozlabs/arch/powerpc/Kconfig
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- linux-ozlabs.orig/arch/powerpc/Kconfig
> +++ linux-ozlabs/arch/powerpc/Kconfig
> @@ -556,6 +556,13 @@ config SCHED_SMT
> 	  when dealing with POWER5 cpus at a cost of slightly increased
> 	  overhead in some places. If unsure say N here.
>=20
> +config PPC_DENORMALISATION
> +	bool "PowerPC denormalisation exception handling"

Should this at least depend on PPC_BOOK3S_64 ?

> +	default "n"
> +	---help---
> +	  Add support for handling denormalisation of single precision
> +	  values.  Useful for bare metal only.  If unsure say Y here.
> +
> config CMDLINE_BOOL
> 	bool "Default bootloader kernel arguments"
>=20
>=20

- k=

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2011-07-13  5:27 ` Kumar Gala
@ 2011-07-13  5:30   ` Michael Neuling
  2012-09-10  6:54   ` Michael Neuling
  1 sibling, 0 replies; 9+ messages in thread
From: Michael Neuling @ 2011-07-13  5:30 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Paul Mackerras, miltonm, linuxppc-dev

In message <5E6FBB75-BE97-4D97-AEA2-EC8EAF1E0ECF@kernel.crashing.org> you wrote
:
> 
> On Jul 11, 2011, at 12:52 AM, Michael Neuling wrote:
> 
> > On POWER6 and POWER7 if the input operand to an instruction is a
> > denormalised single precision binary floating we can take a
> > denormalisation exception where it's expected that the hypervisor =
> (HV=3D1)
> > will fix up the inputs before the instruction is run.
> >=20
> > This adds code to handle this denormalisation exception for POWER6 and
> > POWER7.
> >=20
> > It also add a CONFIG_PPC_DENORMALISATION option and sets it in
> > pseries/ppc64_defconfig.=20
> >=20
> > This is useful on bare metal systems only.  Based on patch from Milton
> > Miller.
> >=20
> > Signed-off-by: Michael Neuling <mikey@neuling.org>
> >=20
> > ---
> > arch/powerpc/Kconfig                   |    7 +
> > arch/powerpc/configs/ppc64_defconfig   |    1=20
> > arch/powerpc/configs/pseries_defconfig |    1=20
> > arch/powerpc/include/asm/ppc-opcode.h  |    2=20
> > arch/powerpc/include/asm/reg.h         |    1=20
> > arch/powerpc/kernel/exceptions-64s.S   |  125 =
> +++++++++++++++++++++++++++++++++
> > 6 files changed, 137 insertions(+)
> >=20
> > Index: linux-ozlabs/arch/powerpc/Kconfig
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > --- linux-ozlabs.orig/arch/powerpc/Kconfig
> > +++ linux-ozlabs/arch/powerpc/Kconfig
> > @@ -556,6 +556,13 @@ config SCHED_SMT
> > 	  when dealing with POWER5 cpus at a cost of slightly increased
> > 	  overhead in some places. If unsure say N here.
> >=20
> > +config PPC_DENORMALISATION
> > +	bool "PowerPC denormalisation exception handling"
> 
> Should this at least depend on PPC_BOOK3S_64 ?

Yep, thanks!

Mikey

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2011-07-13  5:27 ` Kumar Gala
  2011-07-13  5:30   ` Michael Neuling
@ 2012-09-10  6:54   ` Michael Neuling
  2012-09-10  8:13     ` Michael Ellerman
  1 sibling, 1 reply; 9+ messages in thread
From: Michael Neuling @ 2012-09-10  6:54 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, miltonm

On POWER6 and POWER7 if the input operand to an instruction is a
denormalised single precision binary floating we can take a
denormalisation exception where it's expected that the hypervisor (HV=1)
will fix up the inputs before the instruction is run.

This adds code to handle this denormalisation exception for POWER6 and
POWER7.

It also add a CONFIG_PPC_DENORMALISATION option and sets it in
pseries/ppc64_defconfig.

This is useful on bare metal systems only.  Based on patch from Milton
Miller.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
It's been a year since I posted this.  I forgot to repost... I guess I
got distracted by a dog with a fluffy tail or something.

So here's v2 to address Kumar's concern about the Kconfig dependency and
to rebase on a years kernel dev.

If you have any comments, v3 will be out in ~2014.

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 352f416..a454360 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -557,6 +557,14 @@ config SCHED_SMT
 	  when dealing with POWER5 cpus at a cost of slightly increased
 	  overhead in some places. If unsure say N here.
 
+config PPC_DENORMALISATION
+	bool "PowerPC denormalisation exception handling"
+	depends on PPC_BOOK3S_64
+	default "n"
+	---help---
+	  Add support for handling denormalisation of single precision
+	  values.  Useful for bare metal only.  If unsure say Y here.
+
 config CMDLINE_BOOL
 	bool "Default bootloader kernel arguments"
 
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index db27c82..e263e6a 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -51,6 +51,7 @@ CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
 CONFIG_PCCARD=y
 CONFIG_ELECTRA_CF=y
 CONFIG_HOTPLUG_PCI=m
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1f65b3c..c169dfb 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -48,6 +48,7 @@ CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PPC_64K_PAGES=y
 CONFIG_PPC_SUBPAGE_PROT=y
 CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
 CONFIG_HOTPLUG_PCI=m
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 4c25319..5f73ce6 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -126,6 +126,7 @@
 #define PPC_INST_TLBIVAX		0x7c000624
 #define PPC_INST_TLBSRX_DOT		0x7c0006a5
 #define PPC_INST_XXLOR			0xf0000510
+#define PPC_INST_XVCPSGNDP		0xf0000780
 
 #define PPC_INST_NAP			0x4c000364
 #define PPC_INST_SLEEP			0x4c0003a4
@@ -277,6 +278,8 @@
 					       VSX_XX1((s), a, b))
 #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
 					       VSX_XX3((t), a, b))
+#define XVCPSGNDP(t, a, b)	stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
+					       VSX_XX3((t), (a), (b))))
 
 #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
 #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 334be34..d352aa4 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -524,6 +524,7 @@
 
 #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
 #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
+#define   HSRR1_DENORM		0x00100000 /* Denorm exception */
 
 #define SPRN_TBCTL	0x35f	/* PA6T Timebase control register */
 #define   TBCTL_FREEZE		0x0000000000000000ull /* Freeze all tbs */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 39aa97d..6bbfbad 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -275,6 +275,31 @@ vsx_unavailable_pSeries_1:
 	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
 	KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
 
+#ifdef CONFIG_PPC_DENORMALISATION
+	. = 0x1500
+	.global denorm_Hypervisor
+denorm_Hypervisor:
+	HMT_MEDIUM
+	mtspr	SPRN_SPRG_HSCRATCH0,r13
+	mfspr	r13,SPRN_SPRG_HPACA
+	std	r9,PACA_EXGEN+EX_R9(r13)
+	std	r10,PACA_EXGEN+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R11(r13)
+	std	r12,PACA_EXGEN+EX_R12(r13)
+	mfspr	r9,SPRN_SPRG_HSCRATCH0
+	std	r9,PACA_EXGEN+EX_R13(r13)
+	mfcr	r9
+
+	mfspr	r10,SPRN_HSRR1
+	mfspr	r11,SPRN_HSRR0		/* save HSRR0 */
+	andis.	r10,r10,(HSRR1_DENORM)@h /* denorm? */
+	addi	r11,r11,-4		/* HSRR0 is next instruction */
+	bne+	denorm_assist
+
+	EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
+	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
+#endif
+
 #ifdef CONFIG_CBE_RAS
 	STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
 	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
@@ -336,6 +361,103 @@ do_stab_bolted_pSeries:
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
 	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
 
+#ifdef CONFIG_PPC_DENORMALISATION
+denorm_assist:
+BEGIN_FTR_SECTION
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER6 do that here for all FP regs.
+ */
+	mfmsr	r10
+	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
+	xori	r10,r10,(MSR_FE0|MSR_FE1)
+	mtmsrd	r10
+	sync
+	fmr	0,0
+	fmr	1,1
+	fmr	2,2
+	fmr	3,3
+	fmr	4,4
+	fmr	5,5
+	fmr	6,6
+	fmr	7,7
+	fmr	8,8
+	fmr	9,9
+	fmr	10,10
+	fmr	11,11
+	fmr	12,12
+	fmr	13,13
+	fmr	14,14
+	fmr	15,15
+	fmr	16,16
+	fmr	17,17
+	fmr	18,18
+	fmr	19,19
+	fmr	20,20
+	fmr	21,21
+	fmr	22,22
+	fmr	23,23
+	fmr	24,24
+	fmr	25,25
+	fmr	26,26
+	fmr	27,27
+	fmr	28,28
+	fmr	29,29
+	fmr	30,30
+	fmr	31,31
+FTR_SECTION_ELSE
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER7 do that here for the first 32 VSX registers only.
+ */
+	mfmsr	r10
+	oris	r10,r10,MSR_VSX@h
+	mtmsrd	r10
+	sync
+	XVCPSGNDP(0,0,0)
+	XVCPSGNDP(1,1,1)
+	XVCPSGNDP(2,2,2)
+	XVCPSGNDP(3,3,3)
+	XVCPSGNDP(4,4,4)
+	XVCPSGNDP(5,5,5)
+	XVCPSGNDP(6,6,6)
+	XVCPSGNDP(7,7,7)
+	XVCPSGNDP(8,8,8)
+	XVCPSGNDP(9,9,9)
+	XVCPSGNDP(10,10,10)
+	XVCPSGNDP(11,11,11)
+	XVCPSGNDP(12,12,12)
+	XVCPSGNDP(13,13,13)
+	XVCPSGNDP(14,14,14)
+	XVCPSGNDP(15,15,15)
+	XVCPSGNDP(16,16,16)
+	XVCPSGNDP(17,17,17)
+	XVCPSGNDP(18,18,18)
+	XVCPSGNDP(19,19,19)
+	XVCPSGNDP(20,20,20)
+	XVCPSGNDP(21,21,21)
+	XVCPSGNDP(22,22,22)
+	XVCPSGNDP(23,23,23)
+	XVCPSGNDP(24,24,24)
+	XVCPSGNDP(25,25,25)
+	XVCPSGNDP(26,26,26)
+	XVCPSGNDP(27,27,27)
+	XVCPSGNDP(28,28,28)
+	XVCPSGNDP(29,29,29)
+	XVCPSGNDP(30,30,30)
+	XVCPSGNDP(31,31,31)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
+	mtspr	SPRN_HSRR0,r11
+	mtcrf	0x80,r9
+	ld	r9,PACA_EXGEN+EX_R9(r13)
+	ld	r10,PACA_EXGEN+EX_R10(r13)
+	ld	r11,PACA_EXGEN+EX_R11(r13)
+	ld	r12,PACA_EXGEN+EX_R12(r13)
+	ld	r13,PACA_EXGEN+EX_R13(r13)
+	HRFID
+	b	.
+#endif
+
 	.align	7
 	/* moved from 0xe00 */
 	STD_EXCEPTION_HV(., 0xe02, h_data_storage)
@@ -495,6 +617,9 @@ machine_check_common:
         STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+#ifdef CONFIG_PPC_DENORMALISATION
+	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
+#endif
 #ifdef CONFIG_ALTIVEC
 	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
 #else

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2012-09-10  6:54   ` Michael Neuling
@ 2012-09-10  8:13     ` Michael Ellerman
  2012-09-10 10:33       ` Michael Neuling
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Ellerman @ 2012-09-10  8:13 UTC (permalink / raw)
  To: Michael Neuling; +Cc: Paul Mackerras, miltonm, linuxppc-dev

On Mon, 2012-09-10 at 16:54 +1000, Michael Neuling wrote:
> On POWER6 and POWER7 if the input operand to an instruction is a
> denormalised single precision binary floating we can take a
                                               ^
                                               point value?



> diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
> index 4c25319..5f73ce6 100644
> --- a/arch/powerpc/include/asm/ppc-opcode.h
> +++ b/arch/powerpc/include/asm/ppc-opcode.h
> @@ -126,6 +126,7 @@
>  #define PPC_INST_TLBIVAX		0x7c000624
>  #define PPC_INST_TLBSRX_DOT		0x7c0006a5
>  #define PPC_INST_XXLOR			0xf0000510
> +#define PPC_INST_XVCPSGNDP		0xf0000780
>  
>  #define PPC_INST_NAP			0x4c000364
>  #define PPC_INST_SLEEP			0x4c0003a4
> @@ -277,6 +278,8 @@
>  					       VSX_XX1((s), a, b))
>  #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
>  					       VSX_XX3((t), a, b))
> +#define XVCPSGNDP(t, a, b)	stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
> +					       VSX_XX3((t), (a), (b))))

If anyone else is wondering, yes the instruction really is "xvcpsgndp".


> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 334be34..d352aa4 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -524,6 +524,7 @@
>  
>  #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
>  #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
> +#define   HSRR1_DENORM		0x00100000 /* Denorm exception */
>  
>  #define SPRN_TBCTL	0x35f	/* PA6T Timebase control register */
>  #define   TBCTL_FREEZE		0x0000000000000000ull /* Freeze all tbs */
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index 39aa97d..6bbfbad 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -275,6 +275,31 @@ vsx_unavailable_pSeries_1:
>  	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
>  	KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
>  
> +#ifdef CONFIG_PPC_DENORMALISATION
> +	. = 0x1500
> +	.global denorm_Hypervisor
> +denorm_Hypervisor:

The naming pattern seems to be "foo_exception_hv".

> +	HMT_MEDIUM
> +	mtspr	SPRN_SPRG_HSCRATCH0,r13
> +	mfspr	r13,SPRN_SPRG_HPACA
> +	std	r9,PACA_EXGEN+EX_R9(r13)
> +	std	r10,PACA_EXGEN+EX_R10(r13)
> +	std	r11,PACA_EXGEN+EX_R11(r13)
> +	std	r12,PACA_EXGEN+EX_R12(r13)
> +	mfspr	r9,SPRN_SPRG_HSCRATCH0
> +	std	r9,PACA_EXGEN+EX_R13(r13)
> +	mfcr	r9
> +
> +	mfspr	r10,SPRN_HSRR1
> +	mfspr	r11,SPRN_HSRR0		/* save HSRR0 */
> +	andis.	r10,r10,(HSRR1_DENORM)@h /* denorm? */
> +	addi	r11,r11,-4		/* HSRR0 is next instruction */
> +	bne+	denorm_assist

I think only this hunk should be inside the  #ifdef.

ie. we should always handle the exception but if we have no denorm
support you go to unknown_exception(), rather than just landing in fubar
land.

> +	EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
> +	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
> +#endif


> @@ -336,6 +361,103 @@ do_stab_bolted_pSeries:
>  	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
>  	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
>  
> +#ifdef CONFIG_PPC_DENORMALISATION
> +denorm_assist:
> +BEGIN_FTR_SECTION
> +/*
> + * To denormalise we need to move a copy of the register to itself.
> + * For POWER6 do that here for all FP regs.
> + */
> +	mfmsr	r10
> +	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
> +	xori	r10,r10,(MSR_FE0|MSR_FE1)
> +	mtmsrd	r10

So we're enabling FP, and switching the FP exception mode to "ignore".
Which is OK because we are going to switch it all back the way it was on
the way out when we rfid?

> +	sync
> +	fmr	0,0
> +	fmr	1,1
> +	fmr	2,2
> +	fmr	3,3
> +	fmr	4,4
> +	fmr	5,5
> +	fmr	6,6
> +	fmr	7,7
> +	fmr	8,8
> +	fmr	9,9
> +	fmr	10,10
> +	fmr	11,11
> +	fmr	12,12
> +	fmr	13,13
> +	fmr	14,14
> +	fmr	15,15
> +	fmr	16,16
> +	fmr	17,17
> +	fmr	18,18
> +	fmr	19,19
> +	fmr	20,20
> +	fmr	21,21
> +	fmr	22,22
> +	fmr	23,23
> +	fmr	24,24
> +	fmr	25,25
> +	fmr	26,26
> +	fmr	27,27
> +	fmr	28,28
> +	fmr	29,29
> +	fmr	30,30
> +	fmr	31,31
> +FTR_SECTION_ELSE
> +/*
> + * To denormalise we need to move a copy of the register to itself.
> + * For POWER7 do that here for the first 32 VSX registers only.
> + */

Why only the first 32?

> +	mfmsr	r10
> +	oris	r10,r10,MSR_VSX@h
> +	mtmsrd	r10

Here we just enable VSX and exceptions be damned?

> +	sync
> +	XVCPSGNDP(0,0,0)
> +	XVCPSGNDP(1,1,1)
> +	XVCPSGNDP(2,2,2)
> +	XVCPSGNDP(3,3,3)
> +	XVCPSGNDP(4,4,4)
> +	XVCPSGNDP(5,5,5)
> +	XVCPSGNDP(6,6,6)
> +	XVCPSGNDP(7,7,7)
> +	XVCPSGNDP(8,8,8)
> +	XVCPSGNDP(9,9,9)
> +	XVCPSGNDP(10,10,10)
> +	XVCPSGNDP(11,11,11)
> +	XVCPSGNDP(12,12,12)
> +	XVCPSGNDP(13,13,13)
> +	XVCPSGNDP(14,14,14)
> +	XVCPSGNDP(15,15,15)
> +	XVCPSGNDP(16,16,16)
> +	XVCPSGNDP(17,17,17)
> +	XVCPSGNDP(18,18,18)
> +	XVCPSGNDP(19,19,19)
> +	XVCPSGNDP(20,20,20)
> +	XVCPSGNDP(21,21,21)
> +	XVCPSGNDP(22,22,22)
> +	XVCPSGNDP(23,23,23)
> +	XVCPSGNDP(24,24,24)
> +	XVCPSGNDP(25,25,25)
> +	XVCPSGNDP(26,26,26)
> +	XVCPSGNDP(27,27,27)
> +	XVCPSGNDP(28,28,28)
> +	XVCPSGNDP(29,29,29)
> +	XVCPSGNDP(30,30,30)
> +	XVCPSGNDP(31,31,31)
> +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
> +	mtspr	SPRN_HSRR0,r11

Do we not need to restore HSRR1 too?

> +	mtcrf	0x80,r9
> +	ld	r9,PACA_EXGEN+EX_R9(r13)
> +	ld	r10,PACA_EXGEN+EX_R10(r13)
> +	ld	r11,PACA_EXGEN+EX_R11(r13)
> +	ld	r12,PACA_EXGEN+EX_R12(r13)
> +	ld	r13,PACA_EXGEN+EX_R13(r13)
> +	HRFID
> +	b	.
> +#endif
> +
>  	.align	7
>  	/* moved from 0xe00 */
>  	STD_EXCEPTION_HV(., 0xe02, h_data_storage)
> @@ -495,6 +617,9 @@ machine_check_common:
>          STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
>  	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
>  	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
> +#ifdef CONFIG_PPC_DENORMALISATION
> +	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
> +#endif
>  #ifdef CONFIG_ALTIVEC
>  	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
>  #else


Looking forward to your response in 2014 ;)

cheers

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2012-09-10  8:13     ` Michael Ellerman
@ 2012-09-10 10:33       ` Michael Neuling
  2012-09-10 10:35         ` Michael Neuling
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Neuling @ 2012-09-10 10:33 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: Paul Mackerras, miltonm, linuxppc-dev

Michael Ellerman <michael@ellerman.id.au> wrote:

> On Mon, 2012-09-10 at 16:54 +1000, Michael Neuling wrote:
> > On POWER6 and POWER7 if the input operand to an instruction is a
> > denormalised single precision binary floating we can take a
>                                                ^
>                                                point value?

Thanks

> 
> 
> 
> > diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
> > index 4c25319..5f73ce6 100644
> > --- a/arch/powerpc/include/asm/ppc-opcode.h
> > +++ b/arch/powerpc/include/asm/ppc-opcode.h
> > @@ -126,6 +126,7 @@
> >  #define PPC_INST_TLBIVAX		0x7c000624
> >  #define PPC_INST_TLBSRX_DOT		0x7c0006a5
> >  #define PPC_INST_XXLOR			0xf0000510
> > +#define PPC_INST_XVCPSGNDP		0xf0000780
> >  
> >  #define PPC_INST_NAP			0x4c000364
> >  #define PPC_INST_SLEEP			0x4c0003a4
> > @@ -277,6 +278,8 @@
> >  					       VSX_XX1((s), a, b))
> >  #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
> >  					       VSX_XX3((t), a, b))
> > +#define XVCPSGNDP(t, a, b)	stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
> > +					       VSX_XX3((t), (a), (b))))
> 
> If anyone else is wondering, yes the instruction really is
> "xvcpsgndp".

Man, I didn't even notice that.  I must have PPC asm Stockholm Syndrome.

> 
> 
> > diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> > index 334be34..d352aa4 100644
> > --- a/arch/powerpc/include/asm/reg.h
> > +++ b/arch/powerpc/include/asm/reg.h
> > @@ -524,6 +524,7 @@
> >  
> >  #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
> >  #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
> > +#define   HSRR1_DENORM		0x00100000 /* Denorm exception */
> >  
> >  #define SPRN_TBCTL	0x35f	/* PA6T Timebase control register */
> >  #define   TBCTL_FREEZE		0x0000000000000000ull /* Freeze all tbs */
> > diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> > index 39aa97d..6bbfbad 100644
> > --- a/arch/powerpc/kernel/exceptions-64s.S
> > +++ b/arch/powerpc/kernel/exceptions-64s.S
> > @@ -275,6 +275,31 @@ vsx_unavailable_pSeries_1:
> >  	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
> >  	KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
> >  
> > +#ifdef CONFIG_PPC_DENORMALISATION
> > +	. = 0x1500
> > +	.global denorm_Hypervisor
> > +denorm_Hypervisor:
> 
> The naming pattern seems to be "foo_exception_hv".

Thanks, changed.

> 
> > +	HMT_MEDIUM
> > +	mtspr	SPRN_SPRG_HSCRATCH0,r13
> > +	mfspr	r13,SPRN_SPRG_HPACA
> > +	std	r9,PACA_EXGEN+EX_R9(r13)
> > +	std	r10,PACA_EXGEN+EX_R10(r13)
> > +	std	r11,PACA_EXGEN+EX_R11(r13)
> > +	std	r12,PACA_EXGEN+EX_R12(r13)
> > +	mfspr	r9,SPRN_SPRG_HSCRATCH0
> > +	std	r9,PACA_EXGEN+EX_R13(r13)
> > +	mfcr	r9
> > +
> > +	mfspr	r10,SPRN_HSRR1
> > +	mfspr	r11,SPRN_HSRR0		/* save HSRR0 */
> > +	andis.	r10,r10,(HSRR1_DENORM)@h /* denorm? */
> > +	addi	r11,r11,-4		/* HSRR0 is next instruction */
> > +	bne+	denorm_assist
> 
> I think only this hunk should be inside the  #ifdef.
> 
> ie. we should always handle the exception but if we have no denorm
> support you go to unknown_exception(), rather than just landing in fubar
> land.

Yep, thanks.

> 
> > +	EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
> > +	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
> > +#endif
> 
> 
> > @@ -336,6 +361,103 @@ do_stab_bolted_pSeries:
> >  	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
> >  	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
> >  
> > +#ifdef CONFIG_PPC_DENORMALISATION
> > +denorm_assist:
> > +BEGIN_FTR_SECTION
> > +/*
> > + * To denormalise we need to move a copy of the register to itself.
> > + * For POWER6 do that here for all FP regs.
> > + */
> > +	mfmsr	r10
> > +	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
> > +	xori	r10,r10,(MSR_FE0|MSR_FE1)
> > +	mtmsrd	r10
> 
> So we're enabling FP, and switching the FP exception mode to "ignore".
> Which is OK because we are going to switch it all back the way it was on
> the way out when we rfid?

Yep, RFID will take it from HSRR1.

> 
> > +	sync
> > +	fmr	0,0
> > +	fmr	1,1
> > +	fmr	2,2
> > +	fmr	3,3
> > +	fmr	4,4
> > +	fmr	5,5
> > +	fmr	6,6
> > +	fmr	7,7
> > +	fmr	8,8
> > +	fmr	9,9
> > +	fmr	10,10
> > +	fmr	11,11
> > +	fmr	12,12
> > +	fmr	13,13
> > +	fmr	14,14
> > +	fmr	15,15
> > +	fmr	16,16
> > +	fmr	17,17
> > +	fmr	18,18
> > +	fmr	19,19
> > +	fmr	20,20
> > +	fmr	21,21
> > +	fmr	22,22
> > +	fmr	23,23
> > +	fmr	24,24
> > +	fmr	25,25
> > +	fmr	26,26
> > +	fmr	27,27
> > +	fmr	28,28
> > +	fmr	29,29
> > +	fmr	30,30
> > +	fmr	31,31
> > +FTR_SECTION_ELSE
> > +/*
> > + * To denormalise we need to move a copy of the register to itself.
> > + * For POWER7 do that here for the first 32 VSX registers only.
> > + */
> 
> Why only the first 32?

Because it can only happen on the VSX regs that overlap the FP on
POWER7, plus, that's what book IV told me..

> 
> > +	mfmsr	r10
> > +	oris	r10,r10,MSR_VSX@h
> > +	mtmsrd	r10
> 
> Here we just enable VSX and exceptions be damned?

IRQs are hard off (we never enabled them) and we aren't going to take
any page faults with the MMU off also so we shouldn't take any
exceptions.

> 
> > +	sync
> > +	XVCPSGNDP(0,0,0)
> > +	XVCPSGNDP(1,1,1)
> > +	XVCPSGNDP(2,2,2)
> > +	XVCPSGNDP(3,3,3)
> > +	XVCPSGNDP(4,4,4)
> > +	XVCPSGNDP(5,5,5)
> > +	XVCPSGNDP(6,6,6)
> > +	XVCPSGNDP(7,7,7)
> > +	XVCPSGNDP(8,8,8)
> > +	XVCPSGNDP(9,9,9)
> > +	XVCPSGNDP(10,10,10)
> > +	XVCPSGNDP(11,11,11)
> > +	XVCPSGNDP(12,12,12)
> > +	XVCPSGNDP(13,13,13)
> > +	XVCPSGNDP(14,14,14)
> > +	XVCPSGNDP(15,15,15)
> > +	XVCPSGNDP(16,16,16)
> > +	XVCPSGNDP(17,17,17)
> > +	XVCPSGNDP(18,18,18)
> > +	XVCPSGNDP(19,19,19)
> > +	XVCPSGNDP(20,20,20)
> > +	XVCPSGNDP(21,21,21)
> > +	XVCPSGNDP(22,22,22)
> > +	XVCPSGNDP(23,23,23)
> > +	XVCPSGNDP(24,24,24)
> > +	XVCPSGNDP(25,25,25)
> > +	XVCPSGNDP(26,26,26)
> > +	XVCPSGNDP(27,27,27)
> > +	XVCPSGNDP(28,28,28)
> > +	XVCPSGNDP(29,29,29)
> > +	XVCPSGNDP(30,30,30)
> > +	XVCPSGNDP(31,31,31)
> > +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
> > +	mtspr	SPRN_HSRR0,r11
> 
> Do we not need to restore HSRR1 too?

We never changed HSSR1, so yes.

> 
> > +	mtcrf	0x80,r9
> > +	ld	r9,PACA_EXGEN+EX_R9(r13)
> > +	ld	r10,PACA_EXGEN+EX_R10(r13)
> > +	ld	r11,PACA_EXGEN+EX_R11(r13)
> > +	ld	r12,PACA_EXGEN+EX_R12(r13)
> > +	ld	r13,PACA_EXGEN+EX_R13(r13)
> > +	HRFID
> > +	b	.
> > +#endif
> > +
> >  	.align	7
> >  	/* moved from 0xe00 */
> >  	STD_EXCEPTION_HV(., 0xe02, h_data_storage)
> > @@ -495,6 +617,9 @@ machine_check_common:
> >          STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
> >  	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
> >  	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
> > +#ifdef CONFIG_PPC_DENORMALISATION
> > +	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
> > +#endif
> >  #ifdef CONFIG_ALTIVEC
> >  	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
> >  #else
> 
> 
> Looking forward to your response in 2014 ;)

Look at me... confounding expectations!

I'll repost...

Mikey

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] powerpc: add denormalisation exception handling for POWER6/7
  2012-09-10 10:33       ` Michael Neuling
@ 2012-09-10 10:35         ` Michael Neuling
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Neuling @ 2012-09-10 10:35 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, miltonm

On POWER6 and POWER7 if the input operand to an instruction is a
denormalised single precision binary floating point value we can take
a denormalisation exception where it's expected that the hypervisor
(HV=1) will fix up the inputs before the instruction is run.

This adds code to handle this denormalisation exception for POWER6 and
POWER7.

It also add a CONFIG_PPC_DENORMALISATION option and sets it in
pseries/ppc64_defconfig.

This is useful on bare metal systems only.  Based on patch from Milton
Miller.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---

v3 as per mpe's comments.

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 352f416..a454360 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -557,6 +557,14 @@ config SCHED_SMT
 	  when dealing with POWER5 cpus at a cost of slightly increased
 	  overhead in some places. If unsure say N here.
 
+config PPC_DENORMALISATION
+	bool "PowerPC denormalisation exception handling"
+	depends on PPC_BOOK3S_64
+	default "n"
+	---help---
+	  Add support for handling denormalisation of single precision
+	  values.  Useful for bare metal only.  If unsure say Y here.
+
 config CMDLINE_BOOL
 	bool "Default bootloader kernel arguments"
 
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index db27c82..e263e6a 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -51,6 +51,7 @@ CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
 CONFIG_PCCARD=y
 CONFIG_ELECTRA_CF=y
 CONFIG_HOTPLUG_PCI=m
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1f65b3c..c169dfb 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -48,6 +48,7 @@ CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PPC_64K_PAGES=y
 CONFIG_PPC_SUBPAGE_PROT=y
 CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
 CONFIG_HOTPLUG_PCI=m
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 4c25319..5f73ce6 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -126,6 +126,7 @@
 #define PPC_INST_TLBIVAX		0x7c000624
 #define PPC_INST_TLBSRX_DOT		0x7c0006a5
 #define PPC_INST_XXLOR			0xf0000510
+#define PPC_INST_XVCPSGNDP		0xf0000780
 
 #define PPC_INST_NAP			0x4c000364
 #define PPC_INST_SLEEP			0x4c0003a4
@@ -277,6 +278,8 @@
 					       VSX_XX1((s), a, b))
 #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
 					       VSX_XX3((t), a, b))
+#define XVCPSGNDP(t, a, b)	stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
+					       VSX_XX3((t), (a), (b))))
 
 #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
 #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 334be34..d352aa4 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -524,6 +524,7 @@
 
 #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
 #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
+#define   HSRR1_DENORM		0x00100000 /* Denorm exception */
 
 #define SPRN_TBCTL	0x35f	/* PA6T Timebase control register */
 #define   TBCTL_FREEZE		0x0000000000000000ull /* Freeze all tbs */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 39aa97d..5eb0056 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -275,6 +275,31 @@ vsx_unavailable_pSeries_1:
 	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
 	KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
 
+	. = 0x1500
+	.global denorm_Hypervisor
+denorm_exception_hv:
+	HMT_MEDIUM
+	mtspr	SPRN_SPRG_HSCRATCH0,r13
+	mfspr	r13,SPRN_SPRG_HPACA
+	std	r9,PACA_EXGEN+EX_R9(r13)
+	std	r10,PACA_EXGEN+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R11(r13)
+	std	r12,PACA_EXGEN+EX_R12(r13)
+	mfspr	r9,SPRN_SPRG_HSCRATCH0
+	std	r9,PACA_EXGEN+EX_R13(r13)
+	mfcr	r9
+
+#ifdef CONFIG_PPC_DENORMALISATION
+	mfspr	r10,SPRN_HSRR1
+	mfspr	r11,SPRN_HSRR0		/* save HSRR0 */
+	andis.	r10,r10,(HSRR1_DENORM)@h /* denorm? */
+	addi	r11,r11,-4		/* HSRR0 is next instruction */
+	bne+	denorm_assist
+#endif
+
+	EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
+	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
+
 #ifdef CONFIG_CBE_RAS
 	STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
 	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
@@ -336,6 +361,103 @@ do_stab_bolted_pSeries:
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
 	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
 
+#ifdef CONFIG_PPC_DENORMALISATION
+denorm_assist:
+BEGIN_FTR_SECTION
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER6 do that here for all FP regs.
+ */
+	mfmsr	r10
+	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
+	xori	r10,r10,(MSR_FE0|MSR_FE1)
+	mtmsrd	r10
+	sync
+	fmr	0,0
+	fmr	1,1
+	fmr	2,2
+	fmr	3,3
+	fmr	4,4
+	fmr	5,5
+	fmr	6,6
+	fmr	7,7
+	fmr	8,8
+	fmr	9,9
+	fmr	10,10
+	fmr	11,11
+	fmr	12,12
+	fmr	13,13
+	fmr	14,14
+	fmr	15,15
+	fmr	16,16
+	fmr	17,17
+	fmr	18,18
+	fmr	19,19
+	fmr	20,20
+	fmr	21,21
+	fmr	22,22
+	fmr	23,23
+	fmr	24,24
+	fmr	25,25
+	fmr	26,26
+	fmr	27,27
+	fmr	28,28
+	fmr	29,29
+	fmr	30,30
+	fmr	31,31
+FTR_SECTION_ELSE
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER7 do that here for the first 32 VSX registers only.
+ */
+	mfmsr	r10
+	oris	r10,r10,MSR_VSX@h
+	mtmsrd	r10
+	sync
+	XVCPSGNDP(0,0,0)
+	XVCPSGNDP(1,1,1)
+	XVCPSGNDP(2,2,2)
+	XVCPSGNDP(3,3,3)
+	XVCPSGNDP(4,4,4)
+	XVCPSGNDP(5,5,5)
+	XVCPSGNDP(6,6,6)
+	XVCPSGNDP(7,7,7)
+	XVCPSGNDP(8,8,8)
+	XVCPSGNDP(9,9,9)
+	XVCPSGNDP(10,10,10)
+	XVCPSGNDP(11,11,11)
+	XVCPSGNDP(12,12,12)
+	XVCPSGNDP(13,13,13)
+	XVCPSGNDP(14,14,14)
+	XVCPSGNDP(15,15,15)
+	XVCPSGNDP(16,16,16)
+	XVCPSGNDP(17,17,17)
+	XVCPSGNDP(18,18,18)
+	XVCPSGNDP(19,19,19)
+	XVCPSGNDP(20,20,20)
+	XVCPSGNDP(21,21,21)
+	XVCPSGNDP(22,22,22)
+	XVCPSGNDP(23,23,23)
+	XVCPSGNDP(24,24,24)
+	XVCPSGNDP(25,25,25)
+	XVCPSGNDP(26,26,26)
+	XVCPSGNDP(27,27,27)
+	XVCPSGNDP(28,28,28)
+	XVCPSGNDP(29,29,29)
+	XVCPSGNDP(30,30,30)
+	XVCPSGNDP(31,31,31)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
+	mtspr	SPRN_HSRR0,r11
+	mtcrf	0x80,r9
+	ld	r9,PACA_EXGEN+EX_R9(r13)
+	ld	r10,PACA_EXGEN+EX_R10(r13)
+	ld	r11,PACA_EXGEN+EX_R11(r13)
+	ld	r12,PACA_EXGEN+EX_R12(r13)
+	ld	r13,PACA_EXGEN+EX_R13(r13)
+	HRFID
+	b	.
+#endif
+
 	.align	7
 	/* moved from 0xe00 */
 	STD_EXCEPTION_HV(., 0xe02, h_data_storage)
@@ -495,6 +617,7 @@ machine_check_common:
         STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
 #ifdef CONFIG_ALTIVEC
 	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
 #else

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-09-10 10:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-11  5:52 [PATCH] powerpc: add denormalisation exception handling for POWER6/7 Michael Neuling
2011-07-12  3:51 ` Kumar Gala
2011-07-12  4:12   ` Benjamin Herrenschmidt
2011-07-13  5:27 ` Kumar Gala
2011-07-13  5:30   ` Michael Neuling
2012-09-10  6:54   ` Michael Neuling
2012-09-10  8:13     ` Michael Ellerman
2012-09-10 10:33       ` Michael Neuling
2012-09-10 10:35         ` Michael Neuling

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).