iPXE
Defines | Functions
cpuid.c File Reference

x86 CPU feature detection More...

#include <string.h>
#include <errno.h>
#include <ipxe/cpuid.h>

Go to the source code of this file.

Defines

#define colour   0x861d
 Colour for debug messages.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int cpuid_instruction_supported (void)
 Check whether or not CPUID instruction is supported.
int cpuid_supported (uint32_t function)
 Check whether or not CPUID function is supported.
static void x86_intel_features (struct x86_features *features)
 Get Intel-defined x86 CPU features.
static void x86_amd_features (struct x86_features *features)
 Get AMD-defined x86 CPU features.
void x86_features (struct x86_features *features)
 Get x86 CPU features.

Detailed Description

x86 CPU feature detection

Definition in file cpuid.c.


Define Documentation

#define colour   0x861d

Colour for debug messages.

Definition at line 37 of file cpuid.c.

Referenced by cpuid_instruction_supported(), and cpuid_supported().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int cpuid_instruction_supported ( void  ) [static]

Check whether or not CPUID instruction is supported.

Return values:
rcReturn status code

Definition at line 44 of file cpuid.c.

References __asm__(), colour, CPUID_FLAG, DBGC, and ENOTSUP.

Referenced by cpuid_supported().

                                                {
        unsigned long original;
        unsigned long inverted;

        /* Check for instruction existence via flag modifiability */
        __asm__ ( "pushf\n\t"
                  "pushf\n\t"
                  "pop %0\n\t"
                  "mov %0,%1\n\t"
                  "xor %2,%1\n\t"
                  "push %1\n\t"
                  "popf\n\t"
                  "pushf\n\t"
                  "pop %1\n\t"
                  "popf\n\t"
                  : "=&r" ( original ), "=&r" ( inverted )
                  : "ir" ( CPUID_FLAG ) );
        if ( ! ( ( original ^ inverted ) & CPUID_FLAG ) ) {
                DBGC ( colour, "CPUID instruction is not supported\n" );
                return -ENOTSUP;
        }

        return 0;
}
int cpuid_supported ( uint32_t  function)

Check whether or not CPUID function is supported.

Parameters:
functionCPUID function
Return values:
rcReturn status code

Definition at line 75 of file cpuid.c.

References colour, CPUID_AMD_CHECK_MASK, CPUID_EXTENDED, cpuid_instruction_supported(), DBGC, EINVAL, ENOTTY, and rc.

Referenced by cpuid_settings_fetch(), rdtsc_probe(), x86_amd_features(), and x86_intel_features().

                                          {
        uint32_t max_function;
        uint32_t discard_b;
        uint32_t discard_c;
        uint32_t discard_d;
        int rc;

        /* Check that CPUID instruction is available */
        if ( ( rc = cpuid_instruction_supported() ) != 0 )
                return rc;

        /* Find highest supported function number within this family */
        cpuid ( ( function & CPUID_EXTENDED ), 0, &max_function, &discard_b,
                &discard_c, &discard_d );

        /* Fail if maximum function number is meaningless (e.g. if we
         * are attempting to call an extended function on a CPU which
         * does not support them).
         */
        if ( ( max_function & CPUID_AMD_CHECK_MASK ) !=
             ( function & CPUID_AMD_CHECK_MASK ) ) {
                DBGC ( colour, "CPUID invalid maximum function %#08x\n",
                       max_function );
                return -EINVAL;
        }

        /* Fail if this function is not supported */
        if ( function > max_function ) {
                DBGC ( colour, "CPUID function %#08x not supported\n",
                       function );
                return -ENOTTY;
        }

        return 0;
}
static void x86_intel_features ( struct x86_features features) [static]

Get Intel-defined x86 CPU features.

Parameters:
featuresx86 CPU features to fill in

Definition at line 116 of file cpuid.c.

References CPUID_FEATURES, cpuid_supported(), DBGC, x86_feature_registers::ecx, x86_feature_registers::edx, x86_features::intel, and rc.

Referenced by x86_features().

                                                                 {
        uint32_t discard_a;
        uint32_t discard_b;
        int rc;

        /* Check that features are available via CPUID */
        if ( ( rc = cpuid_supported ( CPUID_FEATURES ) ) != 0 ) {
                DBGC ( features, "CPUID has no Intel-defined features\n" );
                return;
        }

        /* Get features */
        cpuid ( CPUID_FEATURES, 0, &discard_a, &discard_b,
                &features->intel.ecx, &features->intel.edx );
        DBGC ( features, "CPUID Intel features: %%ecx=%08x, %%edx=%08x\n",
               features->intel.ecx, features->intel.edx );

}
static void x86_amd_features ( struct x86_features features) [static]

Get AMD-defined x86 CPU features.

Parameters:
featuresx86 CPU features to fill in

Definition at line 140 of file cpuid.c.

References x86_features::amd, CPUID_AMD_FEATURES, cpuid_supported(), DBGC, x86_feature_registers::ecx, x86_feature_registers::edx, and rc.

Referenced by x86_features().

                                                               {
        uint32_t discard_a;
        uint32_t discard_b;
        int rc;

        /* Check that features are available via CPUID */
        if ( ( rc = cpuid_supported ( CPUID_AMD_FEATURES ) ) != 0 ) {
                DBGC ( features, "CPUID has no AMD-defined features\n" );
                return;
        }

        /* Get features */
        cpuid ( CPUID_AMD_FEATURES, 0, &discard_a, &discard_b,
                &features->amd.ecx, &features->amd.edx );
        DBGC ( features, "CPUID AMD features: %%ecx=%08x, %%edx=%08x\n",
               features->amd.ecx, features->amd.edx );
}
void x86_features ( struct x86_features features)

Get x86 CPU features.

Parameters:
featuresx86 CPU features to fill in

Definition at line 163 of file cpuid.c.

References memset(), x86_amd_features(), and x86_intel_features().

Referenced by cpuid_exec(), and hv_check_hv().

                                                    {

        /* Clear all features */
        memset ( features, 0, sizeof ( *features ) );

        /* Get Intel-defined features */
        x86_intel_features ( features );

        /* Get AMD-defined features */
        x86_amd_features ( features );
}