[Libva] [PATCH 1/2] Use the inline CPUID assembly to obtain CPUID string instead of /proc/cpuinfo
Gwenole Beauchesne
gb.devel at gmail.com
Wed Sep 24 02:10:06 PDT 2014
Hi,
Great to see that finally fixed.
2014-09-24 9:13 GMT+02:00 Zhao Yakui <yakui.zhao at intel.com>:
> On some systems there is no access to /proc/cpuinfo. So the inline assembly
> is used directly to detect the CPUID string.
>
> Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
> ---
> src/i965_device_info.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 46 insertions(+)
>
> diff --git a/src/i965_device_info.c b/src/i965_device_info.c
> index 5ebea2a..4ffba61 100755
> --- a/src/i965_device_info.c
> +++ b/src/i965_device_info.c
> @@ -378,6 +378,7 @@ i965_get_device_info(int devid)
> }
> }
>
> +#if 0
> static int intel_driver_detect_cpustring(char *model_id)
> {
> FILE *fp;
> @@ -416,7 +417,52 @@ static int intel_driver_detect_cpustring(char *model_id)
> else
> return -EINVAL;
> }
> +#else
> +static inline void cpuid(unsigned int op,
> + unsigned int *eax, unsigned int *ebx,
> + unsigned int *ecx, unsigned int *edx)
Use uint32_t so that to not make the code below confusing when
different 32-bit/64-bit asm is involved and you are sure the operands
are 32-bits, just say so.
> +{
> + *eax = op;
> + *ecx = 0;
> + /* ecx is often an input as well as an output. */
> + asm volatile("cpuid"
> + : "=a" (*eax),
> + "=b" (*ebx),
> + "=c" (*ecx),
> + "=d" (*edx)
> + : "0" (*eax), "2" (*ecx)
> + :"memory");
> +}
This will likely fail in 32-bit mode. %ebx is the PIC register there.
e.g. use %edi as a temporary in this case. And split into two
versions.
Besides, choose between in/out operands (+) and keep *eax/*ecx
initializations, or use separate outputs and inputs and initialize
eax/ecx there, e.g. "a" (op), "c" (0) and drop the *eax/*ecx lines.
Don't mix both.
> +
> +/*
> + * This function doesn't check the length. And the caller should
> + * assure that the length of input string should be greater than 48.
> + */
> +static int intel_driver_detect_cpustring(char *model_id)
This is totally useless then, worded as is, and doesn't bring in more
robustness. Use dynamic allocation, or model_id + length of model_id.
> +{
> + unsigned int *rdata;
>
> + if (model_id == NULL)
> + return -EINVAL;
> +
> + rdata = (unsigned int *)model_id;
> +
> + /* obtain the max supported extended CPUID info */
> + cpuid(0x80000000, &rdata[0], &rdata[1], &rdata[2], &rdata[3]);
> +
> + /* If the max extended CPUID info is less than 0x80000004, fail */
> + if (rdata[0] < 0x80000004)
> + return -EINVAL;
> +
> + /* obtain the CPUID string */
> + cpuid(0x80000002, &rdata[0], &rdata[1], &rdata[2], &rdata[3]);
> + cpuid(0x80000003, &rdata[4], &rdata[5], &rdata[6], &rdata[7]);
> + cpuid(0x80000004, &rdata[8], &rdata[9], &rdata[10], &rdata[11]);
> +
> + *(model_id + 48) = '\0';
That's model_id[48] = '\0'; much simpler to read.
> + return 0;
> +}
> +#endif
> /*
> * the hook_list for HSW.
> * It is captured by /proc/cpuinfo and the space character is stripped.
> --
> 1.7.10.1
>
> _______________________________________________
> Libva mailing list
> Libva at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/libva
Regards,
--
Gwenole Beauchesne
Intel Corporation SAS / 2 rue de Paris, 92196 Meudon Cedex, France
Registration Number (RCS): Nanterre B 302 456 199
More information about the Libva
mailing list