Skip to content

Commit

Permalink
[efi] Allow use of EFI configuration tables
Browse files Browse the repository at this point in the history
EFI passes in copies of SMBIOS and other system configuration tables
via the EFI system table.  Allow configuration tables to be requested
using a mechanism similar to the current method for requesting EFI
protocols.
  • Loading branch information
Michael Brown committed Dec 4, 2008
1 parent 3a799e9 commit 045a227
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 4 deletions.
33 changes: 33 additions & 0 deletions src/include/gpxe/efi/efi.h
Expand Up @@ -43,6 +43,7 @@

/** An EFI protocol used by gPXE */
struct efi_protocol {
/** GUID */
union {
/** EFI protocol GUID */
EFI_GUID guid;
Expand Down Expand Up @@ -70,6 +71,38 @@ struct efi_protocol {
(_ptr) : (_ptr) ) ), \
}

/** An EFI configuration table used by gPXE */
struct efi_config_table {
/** GUID */
union {
/** EFI configuration table GUID */
EFI_GUID guid;
/** UUID structure understood by gPXE */
union uuid uuid;
} u;
/** Variable containing pointer to configuration table */
void **table;
/** Table is required for operation */
int required;
};

/** Declare an EFI configuration table used by gPXE */
#define __efi_config_table \
__table ( struct efi_config_table, efi_config_tables, 01 )

/** Declare an EFI configuration table to be used by gPXE
*
* @v _table EFI configuration table name
* @v _ptr Pointer to configuration table
* @v _required Table is required for operation
*/
#define EFI_USE_TABLE( _table, _ptr, _required ) \
struct efi_config_table __ ## _table __efi_config_table = { \
.u.guid = _table ## _GUID, \
.table = ( ( void ** ) ( void * ) (_ptr) ), \
.required = (_required), \
}

/** Convert a gPXE status code to an EFI status code
*
* FIXME: actually perform some kind of conversion. gPXE error codes
Expand Down
49 changes: 45 additions & 4 deletions src/interface/efi/efi_entry.c
Expand Up @@ -17,6 +17,7 @@
*/

#include <stdlib.h>
#include <string.h>
#include <gpxe/efi/efi.h>
#include <gpxe/uuid.h>

Expand All @@ -32,6 +33,30 @@ static struct efi_protocol efi_protocols[0] \
static struct efi_protocol efi_protocols_end[0] \
__table_end ( struct efi_protocol, efi_protocols );

/** Declared used EFI configuration tables */
static struct efi_config_table efi_config_tables[0] \
__table_start ( struct efi_config_table, efi_config_tables );
static struct efi_config_table efi_config_tables_end[0] \
__table_end ( struct efi_config_table, efi_config_tables );

/**
* Look up EFI configuration table
*
* @v guid Configuration table GUID
* @ret table Configuration table, or NULL
*/
static void * efi_find_table ( EFI_GUID *guid ) {
unsigned int i;

for ( i = 0 ; i < efi_systab->NumberOfTableEntries ; i++ ) {
if ( memcmp ( &efi_systab->ConfigurationTable[i].VendorGuid,
guid, sizeof ( *guid ) ) == 0 )
return efi_systab->ConfigurationTable[i].VendorTable;
}

return NULL;
}

/**
* EFI entry point
*
Expand All @@ -43,6 +68,7 @@ EFI_STATUS EFIAPI efi_entry ( EFI_HANDLE image_handle,
EFI_SYSTEM_TABLE *systab ) {
EFI_BOOT_SERVICES *bs;
struct efi_protocol *prot;
struct efi_config_table *tab;
EFI_STATUS efirc;

/* Store image handle and system table pointer for future use */
Expand All @@ -65,17 +91,32 @@ EFI_STATUS EFIAPI efi_entry ( EFI_HANDLE image_handle,
}
DBGC ( systab, "EFI handle %p systab %p\n", image_handle, systab );

/* Look up required protocols */
/* Look up used protocols */
bs = systab->BootServices;
for ( prot = efi_protocols ; prot < efi_protocols_end ; prot++ ) {
if ( ( efirc = bs->LocateProtocol ( &prot->u.guid, NULL,
prot->protocol ) ) != 0 ) {
prot->protocol ) ) == 0 ) {
DBGC ( systab, "EFI protocol %s is at %p\n",
uuid_ntoa ( &prot->u.uuid ), *(prot->protocol));
} else {
DBGC ( systab, "EFI does not provide protocol %s\n",
uuid_ntoa ( &prot->u.uuid ) );
/* All protocols are required */
return efirc;
}
DBGC ( systab, "EFI protocol %s is at %p\n",
uuid_ntoa ( &prot->u.uuid ), *(prot->protocol) );
}

/* Look up used configuration tables */
for ( tab = efi_config_tables ; tab < efi_config_tables_end ; tab++ ) {
if ( ( *(tab->table) = efi_find_table ( &tab->u.guid ) ) ) {
DBGC ( systab, "EFI configuration table %s is at %p\n",
uuid_ntoa ( &tab->u.uuid ), *(tab->table) );
} else {
DBGC ( systab, "EFI does not provide configuration "
"table %s\n", uuid_ntoa ( &tab->u.uuid ) );
if ( tab->required )
return EFI_NOT_AVAILABLE_YET;
}
}

/* Call to main() */
Expand Down

0 comments on commit 045a227

Please sign in to comment.