iPXE
Macros | 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.

Macros

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

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)
 
 FILE_SECBOOT (PERMITTED)
 
static int cpuid_settings_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of CPUID setting. More...
 
static int cpuid_settings_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of CPUID setting. More...
 
static void cpuid_settings_init (void)
 Initialise CPUID settings. More...
 
struct init_fn cpuid_settings_init_fn __init_fn (INIT_NORMAL)
 CPUID settings initialiser. More...
 
const struct setting cpuvendor_setting __setting (SETTING_HOST_EXTRA, cpuvendor)
 CPU vendor setting. More...
 
const struct setting cpumodel_setting __setting (SETTING_HOST_EXTRA, cpumodel)
 CPU model setting. More...
 

Variables

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

Detailed Description

x86 CPUID settings

CPUID settings are numerically encoded as:

Bit 31 Extended function Bits 30-24 (bit 22 = 1) Subfunction number Bit 30 (bit 22 = 0) Hypervisor function Bits 29-24 (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.

Macro Definition Documentation

◆ CPUID_TAG

#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 ) )
static uint32_t subfunction
Definition: cpuid.h:90
uint8_t flags
Flags.
Definition: ena.h:18

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 90 of file cpuid_settings.c.

◆ CPUID_FUNCTION

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

Extract starting function number from CPUID setting tag.

Parameters
tagSetting tag
Return values
functionStarting function number

Definition at line 103 of file cpuid_settings.c.

◆ CPUID_SUBFUNCTION

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

Extract subfunction number from CPUID setting tag.

Parameters
tagSetting tag
Return values
subfunctionSubfunction number

Definition at line 111 of file cpuid_settings.c.

◆ CPUID_NUM_FUNCTIONS

#define CPUID_NUM_FUNCTIONS (   tag)    ( ( ( (tag) >> 24 ) & 0x3f ) + 1 )

Extract number of consecutive functions from CPUID setting tag.

Parameters
tagSetting tag
Return values
num_functionsNumber of consecutive functions

Definition at line 119 of file cpuid_settings.c.

◆ CPUID_REGISTERS

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

Extract register array from CPUID setting tag.

Parameters
tagSetting tag
Return values
registersRegister array

Definition at line 127 of file cpuid_settings.c.

◆ CPUID_NUM_REGISTERS

#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 135 of file cpuid_settings.c.

Enumeration Type Documentation

◆ cpuid_registers

CPUID setting tag register indices.

Enumerator
CPUID_EAX 
CPUID_EBX 
CPUID_ECX 
CPUID_EDX 

Definition at line 64 of file cpuid_settings.c.

64  {
65  CPUID_EAX = 0,
66  CPUID_EBX = 1,
67  CPUID_ECX = 2,
68  CPUID_EDX = 3,
69 };

◆ cpuid_flags

CPUID setting tag flags.

Enumerator
CPUID_LITTLE_ENDIAN 
CPUID_USE_SUBFUNCTION 

Definition at line 72 of file cpuid_settings.c.

72  {
73  CPUID_LITTLE_ENDIAN = 0x00800000UL,
74  CPUID_USE_SUBFUNCTION = 0x00400000UL,
75 };

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ cpuid_settings_applies()

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 147 of file cpuid_settings.c.

148  {
149 
150  return ( setting->scope == &cpuid_settings_scope );
151 }
static const struct settings_scope cpuid_settings_scope
CPUID settings scope.
A setting.
Definition: settings.h:24
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:50

References cpuid_settings_scope, and setting::scope.

◆ cpuid_settings_fetch()

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 162 of file cpuid_settings.c.

164  {
165  uint32_t function;
167  uint32_t num_functions;
168  uint32_t registers;
169  uint32_t num_registers;
170  uint32_t buf[4];
172  size_t frag_len;
173  size_t result_len = 0;
174  int rc;
175 
176  /* Call each function in turn */
177  function = CPUID_FUNCTION ( setting->tag );
178  if ( setting->tag & CPUID_USE_SUBFUNCTION ) {
179  function &= ~CPUID_HYPERVISOR;
181  num_functions = 1;
182  } else {
183  subfunction = 0;
184  num_functions = CPUID_NUM_FUNCTIONS ( setting->tag );
185  }
186  for ( ; num_functions-- ; function++ ) {
187 
188  /* Fail if this function is not supported */
189  if ( ( rc = cpuid_supported ( function ) ) != 0 ) {
190  DBGC ( settings, "CPUID function %#08x not supported: "
191  "%s\n", function, strerror ( rc ) );
192  return rc;
193  }
194 
195  /* Issue CPUID */
196  cpuid ( function, subfunction, &buf[CPUID_EAX],
197  &buf[CPUID_EBX], &buf[CPUID_ECX], &buf[CPUID_EDX] );
198  DBGC ( settings, "CPUID %#08x:%x => %#08x:%#08x:%#08x:%#08x\n",
199  function, subfunction, buf[0], buf[1], buf[2], buf[3] );
200 
201  /* Copy results to buffer */
202  registers = CPUID_REGISTERS ( setting->tag );
203  num_registers = CPUID_NUM_REGISTERS ( setting->tag );
204  for ( ; num_registers-- ; registers >>= 2 ) {
205  output = buf[ registers & 0x3 ];
206  if ( ! ( setting->tag & CPUID_LITTLE_ENDIAN ) )
207  output = cpu_to_be32 ( output );
208  frag_len = sizeof ( output );
209  if ( frag_len > len )
210  frag_len = len;
211  memcpy ( data, &output, frag_len );
212  data += frag_len;
213  len -= frag_len;
214  result_len += sizeof ( output );
215  }
216  }
217 
218  /* Set type if not already specified */
219  if ( ! setting->type )
220  setting->type = &setting_type_hexraw;
221 
222  return result_len;
223 }
int cpuid_supported(uint32_t function)
Check whether or not CPUID function is supported.
Definition: cpuid.c:76
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define CPUID_HYPERVISOR
CPUID hypervisor function.
Definition: cpuid.h:38
#define CPUID_FUNCTION(tag)
Extract starting function number from CPUID setting tag.
#define CPUID_SUBFUNCTION(tag)
Extract subfunction number from CPUID setting tag.
#define DBGC(...)
Definition: compiler.h:505
static uint32_t subfunction
Definition: cpuid.h:90
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:44
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define CPUID_REGISTERS(tag)
Extract register array from CPUID setting tag.
#define CPUID_NUM_REGISTERS(tag)
Extract number of registers from CPUID setting tag.
ring len
Length.
Definition: dwmac.h:231
const struct setting_type * type
Setting type.
Definition: settings.h:37
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
A settings block.
Definition: settings.h:133
unsigned int uint32_t
Definition: stdint.h:12
A setting.
Definition: settings.h:24
#define cpu_to_be32(value)
Definition: byteswap.h:111
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define CPUID_NUM_FUNCTIONS(tag)
Extract number of consecutive functions from CPUID setting tag.

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

◆ cpuid_settings_init()

static void cpuid_settings_init ( void  )
static

Initialise CPUID settings.

Definition at line 241 of file cpuid_settings.c.

241  {
242  int rc;
243 
245  "cpuid" ) ) != 0 ) {
246  DBG ( "CPUID could not register settings: %s\n",
247  strerror ( rc ) );
248  return;
249  }
250 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:476
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static struct settings cpuid_settings
CPUID settings.
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

◆ __init_fn()

struct init_fn cpuid_settings_init_fn __init_fn ( INIT_NORMAL  )

CPUID settings initialiser.

◆ __setting() [1/2]

const struct setting cpuvendor_setting __setting ( SETTING_HOST_EXTRA  ,
cpuvendor   
)

CPU vendor setting.

◆ __setting() [2/2]

const struct setting cpumodel_setting __setting ( SETTING_HOST_EXTRA  ,
cpumodel   
)

CPU model setting.

Variable Documentation

◆ cpuid_settings_scope

const struct settings_scope cpuid_settings_scope
static

CPUID settings scope.

Definition at line 138 of file cpuid_settings.c.

Referenced by cpuid_settings_applies().

◆ cpuid_settings_operations

struct settings_operations cpuid_settings_operations
static
Initial value:
= {
}
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.

CPUID settings operations.

Definition at line 226 of file cpuid_settings.c.

◆ cpuid_settings

struct settings cpuid_settings
static
Initial value:
= {
.refcnt = NULL,
.default_scope = &cpuid_settings_scope,
}
static const struct settings_scope cpuid_settings_scope
CPUID settings scope.
static struct settings_operations cpuid_settings_operations
CPUID settings operations.
struct list_head siblings
Sibling settings blocks.
Definition: settings.h:141
struct list_head children
Child settings blocks.
Definition: settings.h:143
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:31
static struct settings cpuid_settings
CPUID settings.
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

CPUID settings.

Definition at line 232 of file cpuid_settings.c.

Referenced by cpuid_settings_init().