iPXE
Defines | Enumerations | Functions | Variables
cpuid_settings.c File Reference

x86 CPUID settings More...

#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/init.h>
#include <ipxe/settings.h>
#include <ipxe/cpuid.h>

Go to the source code of this file.

Defines

#define CPUID_TAG(function, subfunction, flags, num_registers,register1, register2, register3, register4)
 Construct CPUID setting tag.
#define CPUID_FUNCTION(tag)   ( (tag) & 0x800000ffUL )
 Extract starting function number from CPUID setting tag.
#define CPUID_SUBFUNCTION(tag)   ( ( (tag) >> 24 ) & 0x7f )
 Extract subfunction number from CPUID setting tag.
#define CPUID_REGISTERS(tag)   ( ( (tag) >> 8 ) & 0xff )
 Extract register array from CPUID setting tag.
#define CPUID_NUM_REGISTERS(tag)   ( ( ( (tag) >> 16 ) & 0x3 ) + 1 )
 Extract number of registers from CPUID setting tag.

Enumerations

enum  cpuid_registers { CPUID_EAX = 0, CPUID_EBX = 1, CPUID_ECX = 2, CPUID_EDX = 3 }
 CPUID setting tag register indices. More...
enum  cpuid_flags { CPUID_LITTLE_ENDIAN = 0x00800000UL, CPUID_USE_SUBFUNCTION = 0x00400000UL }
 CPUID setting tag flags. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int cpuid_settings_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of CPUID setting.
static int cpuid_settings_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of CPUID setting.
static void cpuid_settings_init (void)
 Initialise CPUID settings.
struct init_fn
cpuid_settings_init_fn 
__init_fn (INIT_NORMAL)
 CPUID settings initialiser.
struct setting cpuvendor_setting __setting (SETTING_HOST_EXTRA, cpuvendor)
 CPU vendor setting.
struct setting cpumodel_setting __setting (SETTING_HOST_EXTRA, cpumodel)
 CPU model setting.

Variables

static struct settings_scope cpuid_settings_scope
 CPUID settings scope.
static struct settings_operations cpuid_settings_operations
 CPUID settings operations.
static struct settings cpuid_settings
 CPUID settings.

Detailed Description

x86 CPUID settings

CPUID settings are numerically encoded as:

Bit 31 Extended function Bits 30-24 (bit 22 = 1) Subfunction number (bit 22 = 0) Number of consecutive functions to call, minus one Bit 23 Return result as little-endian (used for strings) Bit 22 Interpret bits 30-24 as a subfunction number Bits 21-18 Unused Bits 17-16 Number of registers in register array, minus one Bits 15-8 Array of register indices. First entry in array is in bits 9-8. Indices are 0-eax, 1-ebx, 2-ecx, 3-edx. Bits 7-0 Starting function number (excluding "extended" bit)

This encoding scheme is designed to allow the common case of extracting a single register from a single function to be encoded using "cpuid/<register>.<function>", e.g. "cpuid/2.0x80000001" to retrieve the value of ecx from calling CPUID with eax=0x80000001.

A subfunction (i.e. an input value for ecx) may be specified using "cpuid/<subfunction>.0x40.<register>.<function>". This slightly cumbersome syntax is required in order to maintain backwards compatibility with older scripts.

Definition in file cpuid_settings.c.


Define Documentation

#define CPUID_TAG (   function,
  subfunction,
  flags,
  num_registers,
  register1,
  register2,
  register3,
  register4 
)
Value:
( (function) | ( (subfunction) << 24 ) | (flags) |              \
          ( ( (num_registers) - 1 ) << 16 ) |                           \
          ( (register1) << 8 ) | ( (register2) << 10 ) |                \
          ( (register3) << 12 ) | ( (register4) << 14 ) )

Construct CPUID setting tag.

Parameters:
functionStarting function number
subfunctionSubfunction, or number of consecutive functions minus 1
flagsFlags
num_registersNumber of registers in register array
register1First register in register array (or zero, if empty)
register2Second register in register array (or zero, if empty)
register3Third register in register array (or zero, if empty)
register4Fourth register in register array (or zero, if empty)
Return values:
tagSetting tag

Definition at line 88 of file cpuid_settings.c.

#define CPUID_FUNCTION (   tag)    ( (tag) & 0x800000ffUL )

Extract starting function number from CPUID setting tag.

Parameters:
tagSetting tag
Return values:
functionStarting function number

Definition at line 101 of file cpuid_settings.c.

Referenced by cpuid_settings_fetch().

#define CPUID_SUBFUNCTION (   tag)    ( ( (tag) >> 24 ) & 0x7f )

Extract subfunction number from CPUID setting tag.

Parameters:
tagSetting tag
Return values:
subfunctionSubfunction number

Definition at line 109 of file cpuid_settings.c.

Referenced by cpuid_settings_fetch().

#define CPUID_REGISTERS (   tag)    ( ( (tag) >> 8 ) & 0xff )

Extract register array from CPUID setting tag.

Parameters:
tagSetting tag
Return values:
registersRegister array

Definition at line 117 of file cpuid_settings.c.

Referenced by cpuid_settings_fetch().

#define CPUID_NUM_REGISTERS (   tag)    ( ( ( (tag) >> 16 ) & 0x3 ) + 1 )

Extract number of registers from CPUID setting tag.

Parameters:
tagSetting tag
Return values:
num_registersNumber of registers within register array

Definition at line 125 of file cpuid_settings.c.

Referenced by cpuid_settings_fetch().


Enumeration Type Documentation

CPUID setting tag register indices.

Enumerator:
CPUID_EAX 
CPUID_EBX 
CPUID_ECX 
CPUID_EDX 

Definition at line 62 of file cpuid_settings.c.

                     {
        CPUID_EAX = 0,
        CPUID_EBX = 1,
        CPUID_ECX = 2,
        CPUID_EDX = 3,
};

CPUID setting tag flags.

Enumerator:
CPUID_LITTLE_ENDIAN 
CPUID_USE_SUBFUNCTION 

Definition at line 70 of file cpuid_settings.c.

                 {
        CPUID_LITTLE_ENDIAN = 0x00800000UL,
        CPUID_USE_SUBFUNCTION = 0x00400000UL,
};

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int cpuid_settings_applies ( struct settings *settings  __unused,
const struct setting setting 
) [static]

Check applicability of CPUID setting.

Parameters:
settingsSettings block
settingSetting
Return values:
appliesSetting applies within this settings block

Definition at line 137 of file cpuid_settings.c.

References cpuid_settings_scope, and setting::scope.

                                                                    {

        return ( setting->scope == &cpuid_settings_scope );
}
static int cpuid_settings_fetch ( struct settings settings,
struct setting setting,
void *  data,
size_t  len 
) [static]

Fetch value of CPUID setting.

Parameters:
settingsSettings block
settingSetting to fetch
dataBuffer to fill with setting data
lenLength of buffer
Return values:
lenLength of setting data, or negative error

Definition at line 152 of file cpuid_settings.c.

References cpu_to_be32, CPUID_EAX, CPUID_EBX, CPUID_ECX, CPUID_EDX, CPUID_FUNCTION, CPUID_LITTLE_ENDIAN, CPUID_NUM_REGISTERS, CPUID_REGISTERS, CPUID_SUBFUNCTION, cpuid_supported(), CPUID_USE_SUBFUNCTION, DBGC, len, memcpy(), rc, strerror(), subfunction, setting::tag, and setting::type.

                                                           {
        uint32_t function;
        uint32_t subfunction;
        uint32_t num_functions;
        uint32_t registers;
        uint32_t num_registers;
        uint32_t buf[4];
        uint32_t output;
        size_t frag_len;
        size_t result_len = 0;
        int rc;

        /* Call each function in turn */
        function = CPUID_FUNCTION ( setting->tag );
        subfunction = CPUID_SUBFUNCTION ( setting->tag );
        if ( setting->tag & CPUID_USE_SUBFUNCTION ) {
                num_functions = 1;
        } else {
                num_functions = ( subfunction + 1 );
                subfunction = 0;
        }
        for ( ; num_functions-- ; function++ ) {

                /* Fail if this function is not supported */
                if ( ( rc = cpuid_supported ( function ) ) != 0 ) {
                        DBGC ( settings, "CPUID function %#08x not supported: "
                               "%s\n", function, strerror ( rc ) );
                        return rc;
                }

                /* Issue CPUID */
                cpuid ( function, subfunction, &buf[CPUID_EAX],
                        &buf[CPUID_EBX], &buf[CPUID_ECX], &buf[CPUID_EDX] );
                DBGC ( settings, "CPUID %#08x:%x => %#08x:%#08x:%#08x:%#08x\n",
                       function, subfunction, buf[0], buf[1], buf[2], buf[3] );

                /* Copy results to buffer */
                registers = CPUID_REGISTERS ( setting->tag );
                num_registers = CPUID_NUM_REGISTERS ( setting->tag );
                for ( ; num_registers-- ; registers >>= 2 ) {
                        output = buf[ registers & 0x3 ];
                        if ( ! ( setting->tag & CPUID_LITTLE_ENDIAN ) )
                                output = cpu_to_be32 ( output );
                        frag_len = sizeof ( output );
                        if ( frag_len > len )
                                frag_len = len;
                        memcpy ( data, &output, frag_len );
                        data += frag_len;
                        len -= frag_len;
                        result_len += sizeof ( output );
                }
        }

        /* Set type if not already specified */
        if ( ! setting->type )
                setting->type = &setting_type_hexraw;

        return result_len;
}
static void cpuid_settings_init ( void  ) [static]

Initialise CPUID settings.

Definition at line 230 of file cpuid_settings.c.

References DBG, NULL, rc, register_settings(), and strerror().

                                         {
        int rc;

        if ( ( rc = register_settings ( &cpuid_settings, NULL,
                                        "cpuid" ) ) != 0 ) {
                DBG ( "CPUID could not register settings: %s\n",
                      strerror ( rc ) );
                return;
        }
}
struct init_fn cpuid_settings_init_fn __init_fn ( INIT_NORMAL  ) [read]

CPUID settings initialiser.

struct setting cpuvendor_setting __setting ( SETTING_HOST_EXTRA  ,
cpuvendor   
) [read]

CPU vendor setting.

struct setting cpumodel_setting __setting ( SETTING_HOST_EXTRA  ,
cpumodel   
) [read]

CPU model setting.


Variable Documentation

CPUID settings scope.

Definition at line 128 of file cpuid_settings.c.

Referenced by cpuid_settings_applies().

Initial value:
 {
        .applies = cpuid_settings_applies,
        .fetch = cpuid_settings_fetch,
}

CPUID settings operations.

Definition at line 215 of file cpuid_settings.c.

struct settings cpuid_settings [static]
Initial value:
 {
        .refcnt = NULL,
        .siblings = LIST_HEAD_INIT ( cpuid_settings.siblings ),
        .children = LIST_HEAD_INIT ( cpuid_settings.children ),
        .op = &cpuid_settings_operations,
        .default_scope = &cpuid_settings_scope,
}

CPUID settings.

Definition at line 221 of file cpuid_settings.c.