#include <gpxe/uuid.h>
#include <smbios.h>
+/** SMBIOS settings tag magic number */
+#define SMBIOS_TAG_MAGIC 0x5B /* "SmBios" */
+
+/**
+ * Construct SMBIOS empty tag
+ *
+ * @ret tag SMBIOS setting tag
+ */
+#define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
+
/**
* Construct SMBIOS raw-data tag
*
* @ret tag SMBIOS setting tag
*/
#define SMBIOS_RAW_TAG( _type, _structure, _field ) \
- ( ( (_type) << 16 ) | \
+ ( ( SMBIOS_TAG_MAGIC << 24 ) | \
+ ( (_type) << 16 ) | \
( offsetof ( _structure, _field ) << 8 ) | \
( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
* @ret tag SMBIOS setting tag
*/
#define SMBIOS_STRING_TAG( _type, _structure, _field ) \
- ( ( (_type) << 16 ) | \
+ ( ( SMBIOS_TAG_MAGIC << 24 ) | \
+ ( (_type) << 16 ) | \
( offsetof ( _structure, _field ) << 8 ) )
/**
struct setting *setting,
void *data, size_t len ) {
struct smbios_structure structure;
+ unsigned int tag_magic;
unsigned int tag_type;
unsigned int tag_offset;
unsigned int tag_len;
int rc;
/* Split tag into type, offset and length */
- tag_type = ( setting->tag >> 16 );
+ tag_magic = ( setting->tag >> 24 );
+ tag_type = ( ( setting->tag >> 16 ) & 0xff );
tag_offset = ( ( setting->tag >> 8 ) & 0xff );
tag_len = ( setting->tag & 0xff );
- if ( ! tag_type )
+ if ( tag_magic != SMBIOS_TAG_MAGIC )
return -ENOENT;
/* Find SMBIOS structure */
static struct settings smbios_settings = {
.refcnt = NULL,
.name = "smbios",
+ .tag_magic = SMBIOS_EMPTY_TAG,
.siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
.children = LIST_HEAD_INIT ( smbios_settings.children ),
.op = &smbios_settings_operations,
nvo->nvs = nvs;
nvo->fragments = fragments;
settings_init ( &nvo->settings, &nvo_settings_operations, refcnt,
- "nvo" );
+ "nvo", 0 );
}
/**
}
tmp++;
}
+ setting->tag |= (*settings)->tag_magic;
}
/* Identify setting type, if specified */
*
*/
+/** Phantom CLP settings tag magic */
+#define PHN_CLP_TAG_MAGIC 0xc19c1900UL
+
+/** Phantom CLP settings tag magic mask */
+#define PHN_CLP_TAG_MAGIC_MASK 0xffffff00UL
+
/** Phantom CLP data
*
*/
/** gPXE setting */
struct setting *setting;
/** Setting number */
- unsigned int number;
+ unsigned int clp_setting;
};
/** Phantom CLP settings */
* Find Phantom CLP setting
*
* @v setting gPXE setting
- * @v clp_setting Equivalent Phantom CLP setting, or NULL
+ * @v clp_setting Setting number, or 0 if not found
*/
-static struct phantom_clp_setting *
-phantom_find_clp_setting ( struct phantom_nic *phantom,
- struct setting *setting ) {
+static unsigned int
+phantom_clp_setting ( struct phantom_nic *phantom, struct setting *setting ) {
struct phantom_clp_setting *clp_setting;
unsigned int i;
+ /* Search the list of explicitly-defined settings */
for ( i = 0 ; i < ( sizeof ( clp_settings ) /
sizeof ( clp_settings[0] ) ) ; i++ ) {
clp_setting = &clp_settings[i];
if ( setting_cmp ( setting, clp_setting->setting ) == 0 )
- return clp_setting;
+ return clp_setting->clp_setting;
}
+ /* Allow for use of numbered settings */
+ if ( ( setting->tag & PHN_CLP_TAG_MAGIC_MASK ) == PHN_CLP_TAG_MAGIC )
+ return ( setting->tag & ~PHN_CLP_TAG_MAGIC_MASK );
+
DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n",
phantom, setting->name );
- return NULL;
+ return 0;
}
/**
struct phantom_nic_port *phantom_port =
container_of ( settings, struct phantom_nic_port, settings );
struct phantom_nic *phantom = phantom_port->phantom;
- struct phantom_clp_setting *clp_setting;
+ unsigned int clp_setting;
int rc;
/* Find Phantom setting equivalent to gPXE setting */
- clp_setting = phantom_find_clp_setting ( phantom, setting );
+ clp_setting = phantom_clp_setting ( phantom, setting );
if ( ! clp_setting )
return -ENOTSUP;
/* Store setting */
if ( ( rc = phantom_clp_store ( phantom, phantom_port->port,
- clp_setting->number,
- data, len ) ) != 0 ) {
+ clp_setting, data, len ) ) != 0 ) {
DBGC ( phantom, "Phantom %p could not store setting \"%s\": "
"%s\n", phantom, setting->name, strerror ( rc ) );
return rc;
struct phantom_nic_port *phantom_port =
container_of ( settings, struct phantom_nic_port, settings );
struct phantom_nic *phantom = phantom_port->phantom;
- struct phantom_clp_setting *clp_setting;
+ unsigned int clp_setting;
int read_len;
int rc;
/* Find Phantom setting equivalent to gPXE setting */
- clp_setting = phantom_find_clp_setting ( phantom, setting );
+ clp_setting = phantom_clp_setting ( phantom, setting );
if ( ! clp_setting )
return -ENOTSUP;
/* Fetch setting */
if ( ( read_len = phantom_clp_fetch ( phantom, phantom_port->port,
- clp_setting->number,
- data, len ) ) < 0 ) {
+ clp_setting, data, len ) ) < 0 ){
rc = read_len;
DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": "
"%s\n", phantom, setting->name, strerror ( rc ) );
phantom_port->port = i;
settings_init ( &phantom_port->settings,
&phantom_settings_operations,
- &netdev->refcnt, "clp" );
+ &netdev->refcnt, "clp", PHN_CLP_TAG_MAGIC );
}
/* BUG5945 - need to hack PCI config space on P3 B1 silicon.
struct refcnt *refcnt;
/** Name */
const char *name;
+ /** Tag magic
+ *
+ * This value will be ORed in to any numerical tags
+ * constructed by parse_setting_name(), and can be used to
+ * avoid e.g. attempting to retrieve the subnet mask from
+ * SMBIOS, or the system UUID from DHCP.
+ */
+ unsigned int tag_magic;
/** Parent settings block */
struct settings *parent;
/** Sibling settings blocks */
* @v op Settings block operations
* @v refcnt Containing object reference counter, or NULL
* @v name Settings block name
+ * @v tag_magic Tag magic
*/
static inline void settings_init ( struct settings *settings,
struct settings_operations *op,
struct refcnt *refcnt,
- const char *name ) {
+ const char *name,
+ unsigned int tag_magic ) {
INIT_LIST_HEAD ( &settings->siblings );
INIT_LIST_HEAD ( &settings->children );
settings->op = op;
settings->refcnt = refcnt;
settings->name = name;
+ settings->tag_magic = tag_magic;
}
/**
struct refcnt *refcnt,
const char *name ) {
settings_init ( &simple->settings, &simple_settings_operations,
- refcnt, name );
+ refcnt, name, 0 );
}
/**
INIT_LIST_HEAD ( &netdev->rx_queue );
settings_init ( netdev_settings ( netdev ),
&netdev_settings_operations, &netdev->refcnt,
- netdev->name );
+ netdev->name, 0 );
netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
}
return netdev;
dhcppkt_init ( &dhcpset->dhcppkt, data, len );
settings_init ( &dhcpset->settings,
&dhcpset_settings_operations, &dhcpset->refcnt,
- DHCP_SETTINGS_NAME );
+ DHCP_SETTINGS_NAME, 0 );
}
return dhcpset;
}