Subject: Re: rdmsr() function
To: None <phlox-netbsd-i386@fnop.net, port-i386@NetBSD.org>
From: List Mail User <track@Plectere.com>
List: port-i386
Date: 09/24/2004 01:46:07
	Hi,

	I've been watching this exchange for a while, and now that it seems
to be winding up, the time to correct the problems has come;  Two primary
issues - the constraint letter 'D' is for the "edi" register not for the
"edx" register (which is constrained with 'd'), AND the use of the 'A'
constraint makes an explicit reference to BOTH "eax" and "edx" so no
second argument/constraint is needed - also, the high order and low order
bits are reversed in some cases.

	Corrected (and simpler/smaller - two or three insns. each) functions
are below:

static __inline u_int64_t
rdmsr64(u_int msr)
{
     u_int64_t rv;

     __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr));

     return rv;
}

static __inline void
wrmsr64(u_int msr, u_int64_t newval)
{ 
	__asm __volatile("wrmsr" : : "A" (newval), "c" (msr));
}

	Hope this helps some,

	Paul Shupak

>From port-i386-owner-track=Plectere.com@NetBSD.org Thu Sep 23 18:04:41 2004
>Delivered-To: port-i386@netbsd.org
>Date: Fri, 24 Sep 2004 02:04:10 +0100
>From: Rui Paulo <phlox-netbsd-i386@fnop.net>
>To: port-i386@NetBSD.org
>Subject: Re: rdmsr() function
>Mail-Followup-To: port-i386@NetBSD.org
>References: <20040921182100.GA10493@pheisar.fnop.net> <7378E4A6-0C28-11D9-A492-000A957650EC@shagadelic.org> <20040922204526.GA14238@pheisar.fnop.net> <5700D87E-0CDF-11D9-A492-000A957650EC@shagadelic.org> <20040922231447.GA23514@pheisar.fnop.net>
>Mime-Version: 1.0
>Content-Type: text/plain; charset=us-ascii
>Content-Disposition: inline
>In-Reply-To: <20040922231447.GA23514@pheisar.fnop.net>
>User-Agent: Mutt/1.4.2.1i
>Sender: port-i386-owner@NetBSD.org
>Precedence: list
>
>On 2004.09.23 00:14:47 +0000, Rui Paulo wrote:
>> Thanks for you reply.
>> Here is the diff with the changes you suggested:
>> 
>> Index: cpufunc.h
>> ===================================================================
>> RCS file: /cvsroot/src/sys/arch/i386/include/cpufunc.h,v
>> retrieving revision 1.28
>> diff -u -r1.28 cpufunc.h
>> --- cpufunc.h	14 Jan 2004 11:31:55 -0000	1.28
>> +++ cpufunc.h	22 Sep 2004 23:12:48 -0000
>> @@ -245,6 +245,19 @@
>>  	return (rv);
>>  }
>>  
>> +static __inline u_int64_t
>> +rdmsr64(u_int msr)
>> +{       
>> +	u_int64_t rv;
>> +	u_int32_t regs[2];
>> +        
>> +	__asm __volatile("rdmsr" : "=A" (regs[0]), "=D" (regs[1]) : "c" (msr));
>> +	rv = ((u_int64_t) regs[1] << 32) | regs[0];
>> +
>> +	return (rv);
>> +
>> +} 
>> +
>>  static __inline void
>>  wrmsr(u_int msr, u_int64_t newval)
>>  {
>> @@ -252,6 +265,13 @@
>>  }
>>  
>>  static __inline void
>> +wrmsr64(u_int msr, u_int64_t newval)
>> +{
>> +	__asm __volatile("wrmsr" : : "A" (newval >> 32), 
>> +			 "D" (newval & 0xffffffff), "c" (msr));
>> +}
>> +
>> +static __inline void
>>  wbinvd(void)
>>  {
>>  	__asm __volatile("wbinvd");
>> 
>
># "A" : Specifies the `a' or `d' registers. This is primarily useful
># for 64-bit integer values intended to be returned with the `d'
># register holding the most significant bits and the `a' register
># holding the least significant bits.
>So, we don't need the rdmsr64() version. Sorry for the hassle.
>
>Regards.
>-- 
>Rui Paulo                          "Simplicity is the ultimate sophistication."
>                                      -- Leonardo da Vinci
>