All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sparc: cleaned up FPU version probing
@ 2011-01-27 11:06 Daniel Hellstrom
  2011-01-27 11:14 ` Richard Mortimer
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Daniel Hellstrom @ 2011-01-27 11:06 UTC (permalink / raw)
  To: sparclinux

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 arch/sparc/include/asm/psr.h |   51 ++++++++++++++++++++++++++++++++++++++++++
 arch/sparc/kernel/cpu.c      |   11 +++++---
 2 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h
index b8c0e5f..3b34c5a 100644
--- a/arch/sparc/include/asm/psr.h
+++ b/arch/sparc/include/asm/psr.h
@@ -6,11 +6,14 @@
  *        PSTATE.PRIV for the current CPU privilege level.
  *
  * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2011 Daniel Hellstrom (daniel@gaisler.com)
  */
 
 #ifndef __LINUX_SPARC_PSR_H
 #define __LINUX_SPARC_PSR_H
 
+#include <linux/const.h>
+
 /* The Sparc PSR fields are laid out as the following:
  *
  *  ------------------------------------------------------------------------
@@ -34,6 +37,54 @@
 #define PSR_N       0x00800000         /* negative bit               */
 #define PSR_VERS    0x0f000000         /* cpu-version field          */
 #define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
+#define PSR_CWP_SHIFT     0
+#define PSR_ET_SHIFT      5
+#define PSR_PS_SHIFT      6
+#define PSR_S_SHIFT       7
+#define PSR_PIL_SHIFT     8
+#define PSR_EF_SHIFT      12
+#define PSR_EC_SHIFT      13
+#define PSR_SYSCALL_SHIFT 14
+#define PSR_LE_SHIFT      15
+#define PSR_ICC_SHIFT     20
+#define PSR_C_SHIFT       20
+#define PSR_V_SHIFT       21
+#define PSR_Z_SHIFT       22
+#define PSR_N_SHIFT       23
+#define PSR_VERS_SHIFT    24
+#define PSR_IMPL_SHIFT    28
+
+/*
+ * The SPARC v7/v8/v9 FPU FSR Register bits. fcc on v7/v8 is equal to
+ * fcc0 on v9.
+ */
+#define FSR_CEXC    0x0000001f             /* current exception      */
+#define FSR_AEXC    0x000003e0             /* accured exception      */
+#define FSR_FCC0    0x00000c00             /* FP condition code 0    */
+#define FSR_QNE     0x00002000             /* FQ not empty           */
+#define FSR_FTT     0x0001c000             /* FP trap type           */
+#define FSR_VER     0x000e0000             /* FPU version            */
+#define FSR_NS      0x00400000             /* Non standard FP        */
+#define FSR_TEM     0x0f800000             /* FPU trap enable mask   */
+#define FSR_RD      0xc0000000             /* Rounding direction     */
+#define FSR_FCC1    _AC(0x00300000000, UL) /* v9 FP condition code 1 */
+#define FSR_FCC2    _AC(0x0c00000000, UL)  /* v9 FP condition code 2 */
+#define FSR_FCC3    _AC(0x3000000000, UL)  /* v9 FP condition code 3 */
+#define FSR_CEXC_SHIFT  0
+#define FSR_AEXC_SHIFT  5
+#define FSR_FCC0_SHIFT  10
+#define FSR_QNE_SHIFT   13
+#define FSR_FTT_SHIFT   14
+#define FSR_VER_SHIFT   17
+#define FSR_NS_SHIFT    22
+#define FSR_TEM_SHIFT   23
+#define FSR_RD_SHIFT    30
+#define FSR_FCC1_SHIFT  32
+#define FSR_FCC2_SHIFT  34
+#define FSR_FCC3_SHIFT  36
+
+/* FSR.ver=7 when no FPU available */
+#define FSR_VER_NOFPU 7
 
 #ifdef __KERNEL__
 
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 7925c54..bc8d5ef 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -318,15 +318,18 @@ void __cpuinit cpu_probe(void)
 	int psr_impl, psr_vers, fpu_vers;
 	int psr;
 
-	psr_impl = ((get_psr() >> 28) & 0xf);
-	psr_vers = ((get_psr() >> 24) & 0xf);
+	psr_impl = ((get_psr() & PSR_IMPL) >> PSR_IMPL_SHIFT);
+	psr_vers = ((get_psr() & PSR_VERS) >> PSR_VERS_SHIFT);
 
 	psr = get_psr();
 	put_psr(psr | PSR_EF);
 #ifdef CONFIG_SPARC_LEON
-	fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
+	if (get_psr() & PSR_EF)
+		fpu_vers =  (get_fsr() & FSR_VER) >> FSR_VER_SHIFT;
+	else
+		fpu_vers = FSR_VER_NOFPU;
 #else
-	fpu_vers = ((get_fsr() >> 17) & 0x7);
+	fpu_vers = ((get_fsr() & FSR_VER) >> FSR_VER_SHIFT);
 #endif
 
 	put_psr(psr);
-- 
1.5.4


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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
@ 2011-01-27 11:14 ` Richard Mortimer
  2011-01-27 11:21 ` Richard Mortimer
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Richard Mortimer @ 2011-01-27 11:14 UTC (permalink / raw)
  To: sparclinux



On 27/01/2011 11:06, Daniel Hellstrom wrote:
> Signed-off-by: Daniel Hellstrom<daniel@gaisler.com>
> ---
>   arch/sparc/include/asm/psr.h |   51 ++++++++++++++++++++++++++++++++++++++++++
>   arch/sparc/kernel/cpu.c      |   11 +++++---
>   2 files changed, 58 insertions(+), 4 deletions(-)
>
...

> diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
> index 7925c54..bc8d5ef 100644
> --- a/arch/sparc/kernel/cpu.c
> +++ b/arch/sparc/kernel/cpu.c
> @@ -318,15 +318,18 @@ void __cpuinit cpu_probe(void)
>   	int psr_impl, psr_vers, fpu_vers;
>   	int psr;
>
> -	psr_impl = ((get_psr()>>  28)&  0xf);
> -	psr_vers = ((get_psr()>>  24)&  0xf);
> +	psr_impl = ((get_psr()&  PSR_IMPL)>>  PSR_IMPL_SHIFT);
This is going to break. If the top bit of psr_impl is set it
will get sign extended when the left shift is done.

> +	psr_vers = ((get_psr()&  PSR_VERS)>>  PSR_VERS_SHIFT);
>
>   	psr = get_psr();
>   	put_psr(psr | PSR_EF);
>   #ifdef CONFIG_SPARC_LEON
> -	fpu_vers = get_psr()&  PSR_EF ? ((get_fsr()>>  17)&  0x7) : 7;
> +	if (get_psr()&  PSR_EF)
> +		fpu_vers =  (get_fsr()&  FSR_VER)>>  FSR_VER_SHIFT;
> +	else
> +		fpu_vers = FSR_VER_NOFPU;
>   #else
> -	fpu_vers = ((get_fsr()>>  17)&  0x7);
> +	fpu_vers = ((get_fsr()&  FSR_VER)>>  FSR_VER_SHIFT);
>   #endif
>
>   	put_psr(psr);

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
  2011-01-27 11:14 ` Richard Mortimer
@ 2011-01-27 11:21 ` Richard Mortimer
  2011-01-27 17:34 ` Sam Ravnborg
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Richard Mortimer @ 2011-01-27 11:21 UTC (permalink / raw)
  To: sparclinux

On 27/01/2011 11:14, Richard Mortimer wrote:
>
>
> On 27/01/2011 11:06, Daniel Hellstrom wrote:
>> Signed-off-by: Daniel Hellstrom<daniel@gaisler.com>
>> ---
>> arch/sparc/include/asm/psr.h | 51
>> ++++++++++++++++++++++++++++++++++++++++++
>> arch/sparc/kernel/cpu.c | 11 +++++---
>> 2 files changed, 58 insertions(+), 4 deletions(-)
>>
> ...
>
>> diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
>> index 7925c54..bc8d5ef 100644
>> --- a/arch/sparc/kernel/cpu.c
>> +++ b/arch/sparc/kernel/cpu.c
>> @@ -318,15 +318,18 @@ void __cpuinit cpu_probe(void)
>> int psr_impl, psr_vers, fpu_vers;
>> int psr;
>>
>> - psr_impl = ((get_psr()>> 28)& 0xf);
>> - psr_vers = ((get_psr()>> 24)& 0xf);
>> + psr_impl = ((get_psr()& PSR_IMPL)>> PSR_IMPL_SHIFT);
> This is going to break. If the top bit of psr_impl is set it
> will get sign extended when the left shift is done.
Of course I meant right shift :-)

>
>> + psr_vers = ((get_psr()& PSR_VERS)>> PSR_VERS_SHIFT);
>>
>> psr = get_psr();
>> put_psr(psr | PSR_EF);
>> #ifdef CONFIG_SPARC_LEON
>> - fpu_vers = get_psr()& PSR_EF ? ((get_fsr()>> 17)& 0x7) : 7;
>> + if (get_psr()& PSR_EF)
>> + fpu_vers = (get_fsr()& FSR_VER)>> FSR_VER_SHIFT;
>> + else
>> + fpu_vers = FSR_VER_NOFPU;
>> #else
>> - fpu_vers = ((get_fsr()>> 17)& 0x7);
>> + fpu_vers = ((get_fsr()& FSR_VER)>> FSR_VER_SHIFT);
>> #endif
>>
>> put_psr(psr);

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
  2011-01-27 11:14 ` Richard Mortimer
  2011-01-27 11:21 ` Richard Mortimer
@ 2011-01-27 17:34 ` Sam Ravnborg
  2011-01-27 17:36 ` Sam Ravnborg
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sam Ravnborg @ 2011-01-27 17:34 UTC (permalink / raw)
  To: sparclinux

On Thu, Jan 27, 2011 at 11:14:16AM +0000, Richard Mortimer wrote:
>
>
> On 27/01/2011 11:06, Daniel Hellstrom wrote:
>> Signed-off-by: Daniel Hellstrom<daniel@gaisler.com>
>> ---
>>   arch/sparc/include/asm/psr.h |   51 ++++++++++++++++++++++++++++++++++++++++++
>>   arch/sparc/kernel/cpu.c      |   11 +++++---
>>   2 files changed, 58 insertions(+), 4 deletions(-)
>>
> ...
>
>> diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
>> index 7925c54..bc8d5ef 100644
>> --- a/arch/sparc/kernel/cpu.c
>> +++ b/arch/sparc/kernel/cpu.c
>> @@ -318,15 +318,18 @@ void __cpuinit cpu_probe(void)
>>   	int psr_impl, psr_vers, fpu_vers;
>>   	int psr;
>>
>> -	psr_impl = ((get_psr()>>  28)&  0xf);
>> -	psr_vers = ((get_psr()>>  24)&  0xf);
>> +	psr_impl = ((get_psr()&  PSR_IMPL)>>  PSR_IMPL_SHIFT);
> This is going to break. If the top bit of psr_impl is set it
> will get sign extended when the left shift is done.

That would not matter as we use the " & PSR_IMPL" to clear
the unused upper bits.
So IMO the patch is correct.

	Sam

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
                   ` (2 preceding siblings ...)
  2011-01-27 17:34 ` Sam Ravnborg
@ 2011-01-27 17:36 ` Sam Ravnborg
  2011-01-27 18:39 ` Richard Mortimer
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sam Ravnborg @ 2011-01-27 17:36 UTC (permalink / raw)
  To: sparclinux

On Thu, Jan 27, 2011 at 12:06:32PM +0100, Daniel Hellstrom wrote:
> Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>

Hi Daniel.
Thanks for cleaning up this.

Acked-by: Sam Ravnborg <sam@ravnborg.org>

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
                   ` (3 preceding siblings ...)
  2011-01-27 17:36 ` Sam Ravnborg
@ 2011-01-27 18:39 ` Richard Mortimer
  2011-01-27 19:36 ` Sam Ravnborg
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Richard Mortimer @ 2011-01-27 18:39 UTC (permalink / raw)
  To: sparclinux



On 27/01/2011 17:34, Sam Ravnborg wrote:
> On Thu, Jan 27, 2011 at 11:14:16AM +0000, Richard Mortimer wrote:
>>
>>
>> On 27/01/2011 11:06, Daniel Hellstrom wrote:
>>> Signed-off-by: Daniel Hellstrom<daniel@gaisler.com>
>>> ---
>>>    arch/sparc/include/asm/psr.h |   51 ++++++++++++++++++++++++++++++++++++++++++
>>>    arch/sparc/kernel/cpu.c      |   11 +++++---
>>>    2 files changed, 58 insertions(+), 4 deletions(-)
>>>
>> ...
>>
>>> diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
>>> index 7925c54..bc8d5ef 100644
>>> --- a/arch/sparc/kernel/cpu.c
>>> +++ b/arch/sparc/kernel/cpu.c
>>> @@ -318,15 +318,18 @@ void __cpuinit cpu_probe(void)
>>>    	int psr_impl, psr_vers, fpu_vers;
>>>    	int psr;
>>>
>>> -	psr_impl = ((get_psr()>>   28)&   0xf);
>>> -	psr_vers = ((get_psr()>>   24)&   0xf);
>>> +	psr_impl = ((get_psr()&   PSR_IMPL)>>   PSR_IMPL_SHIFT);
>> This is going to break. If the top bit of psr_impl is set it
>> will get sign extended when the left shift is done.
>
> That would not matter as we use the "&  PSR_IMPL" to clear
> the unused upper bits.
> So IMO the patch is correct.
>
I'm not sure. But I'm willing to be pursuaded.

Daniel changed the order of things. The shift is now done after the 
mask. Previously the mask was using 0xf and now it is using 0xf0000000.
e.g.
originally (0x8??????? >> 28)  gives 0xfffffff8 which is masked by 0xf 
to give 8

but now (0x8??????? & 0xf0000000) gives 0x80000000 which is shifted right 28
to give 0xfffffff8.

I must admit that I haven't looked at the defition of get_psr() but I 
think it returns an int and even if it returns unsigned I would be wary 
of leaving it as is because it is fragile in that particular case.

Regards

Richard

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
                   ` (4 preceding siblings ...)
  2011-01-27 18:39 ` Richard Mortimer
@ 2011-01-27 19:36 ` Sam Ravnborg
  2011-01-28 23:09 ` David Miller
  2011-01-31 17:00 ` Daniel Hellstrom
  7 siblings, 0 replies; 9+ messages in thread
From: Sam Ravnborg @ 2011-01-27 19:36 UTC (permalink / raw)
  To: sparclinux

On Thu, Jan 27, 2011 at 06:39:47PM +0000, Richard Mortimer wrote:
>
>
> On 27/01/2011 17:34, Sam Ravnborg wrote:
>> On Thu, Jan 27, 2011 at 11:14:16AM +0000, Richard Mortimer wrote:
>>>
>>>
>>> On 27/01/2011 11:06, Daniel Hellstrom wrote:
>>>> Signed-off-by: Daniel Hellstrom<daniel@gaisler.com>
>>>> ---
>>>>    arch/sparc/include/asm/psr.h |   51 ++++++++++++++++++++++++++++++++++++++++++
>>>>    arch/sparc/kernel/cpu.c      |   11 +++++---
>>>>    2 files changed, 58 insertions(+), 4 deletions(-)
>>>>
>>> ...
>>>
>>>> diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
>>>> index 7925c54..bc8d5ef 100644
>>>> --- a/arch/sparc/kernel/cpu.c
>>>> +++ b/arch/sparc/kernel/cpu.c
>>>> @@ -318,15 +318,18 @@ void __cpuinit cpu_probe(void)
>>>>    	int psr_impl, psr_vers, fpu_vers;
>>>>    	int psr;
>>>>
>>>> -	psr_impl = ((get_psr()>>   28)&   0xf);
>>>> -	psr_vers = ((get_psr()>>   24)&   0xf);
>>>> +	psr_impl = ((get_psr()&   PSR_IMPL)>>   PSR_IMPL_SHIFT);
>>> This is going to break. If the top bit of psr_impl is set it
>>> will get sign extended when the left shift is done.
>>
>> That would not matter as we use the "&  PSR_IMPL" to clear
>> the unused upper bits.
>> So IMO the patch is correct.
>>
> I'm not sure. But I'm willing to be pursuaded.
>
> Daniel changed the order of things. The shift is now done after the  
> mask. Previously the mask was using 0xf and now it is using 0xf0000000.
> e.g.
> originally (0x8??????? >> 28)  gives 0xfffffff8 which is masked by 0xf  
> to give 8
>
> but now (0x8??????? & 0xf0000000) gives 0x80000000 which is shifted right 28
> to give 0xfffffff8.

You are right. I was only looking at the case where we shifted 17.

But get_psr() return an unsigned int:

   static inline unsigned int get_psr(void)

And same does get_fsr().

I checked a few drivers and it seems to be a common pattern to rely
on use of unisged variables.

If we want to be more explicit we can do:

	u32 psr;

	psr = get_psr();
	psr_impl = (psr & PSR_IMPL) >> PSR_IMPL_SHIFT;

I assume gcc will generate equal code for this.
But this looks like overkill.

The mixed use of unsigned int and int in this file also looks
like something to be cleaned up...

	Sam

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
                   ` (5 preceding siblings ...)
  2011-01-27 19:36 ` Sam Ravnborg
@ 2011-01-28 23:09 ` David Miller
  2011-01-31 17:00 ` Daniel Hellstrom
  7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2011-01-28 23:09 UTC (permalink / raw)
  To: sparclinux

From: Sam Ravnborg <sam@ravnborg.org>
Date: Thu, 27 Jan 2011 20:36:03 +0100

> If we want to be more explicit we can do:
> 
> 	u32 psr;
> 
> 	psr = get_psr();
> 	psr_impl = (psr & PSR_IMPL) >> PSR_IMPL_SHIFT;
> 
> I assume gcc will generate equal code for this.
> But this looks like overkill.
> 
> The mixed use of unsigned int and int in this file also looks
> like something to be cleaned up...

Daniel, please respin your patch so that we explicitly use unsigned
variables here as Sam suggests, and thus avoid the sign-extension
issues during the right-shift operations.

Thanks.

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

* Re: [PATCH] sparc: cleaned up FPU version probing
  2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
                   ` (6 preceding siblings ...)
  2011-01-28 23:09 ` David Miller
@ 2011-01-31 17:00 ` Daniel Hellstrom
  7 siblings, 0 replies; 9+ messages in thread
From: Daniel Hellstrom @ 2011-01-31 17:00 UTC (permalink / raw)
  To: sparclinux

David Miller wrote:

>From: Sam Ravnborg <sam@ravnborg.org>
>Date: Thu, 27 Jan 2011 20:36:03 +0100
>
>  
>
>>If we want to be more explicit we can do:
>>
>>	u32 psr;
>>
>>	psr = get_psr();
>>	psr_impl = (psr & PSR_IMPL) >> PSR_IMPL_SHIFT;
>>
>>I assume gcc will generate equal code for this.
>>But this looks like overkill.
>>
>>The mixed use of unsigned int and int in this file also looks
>>like something to be cleaned up...
>>    
>>
>
>Daniel, please respin your patch so that we explicitly use unsigned
>variables here as Sam suggests, and thus avoid the sign-extension
>issues during the right-shift operations.
>  
>
Thanks, I will do that.

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

end of thread, other threads:[~2011-01-31 17:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-27 11:06 [PATCH] sparc: cleaned up FPU version probing Daniel Hellstrom
2011-01-27 11:14 ` Richard Mortimer
2011-01-27 11:21 ` Richard Mortimer
2011-01-27 17:34 ` Sam Ravnborg
2011-01-27 17:36 ` Sam Ravnborg
2011-01-27 18:39 ` Richard Mortimer
2011-01-27 19:36 ` Sam Ravnborg
2011-01-28 23:09 ` David Miller
2011-01-31 17:00 ` Daniel Hellstrom

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.