summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/gpxe/efi/efi.h33
-rw-r--r--src/interface/efi/efi_entry.c49
2 files changed, 78 insertions, 4 deletions
diff --git a/src/include/gpxe/efi/efi.h b/src/include/gpxe/efi/efi.h
index 8c9f789a..b46d5ca5 100644
--- a/src/include/gpxe/efi/efi.h
+++ b/src/include/gpxe/efi/efi.h
@@ -43,6 +43,7 @@
/** An EFI protocol used by gPXE */
struct efi_protocol {
+ /** GUID */
union {
/** EFI protocol GUID */
EFI_GUID guid;
@@ -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
diff --git a/src/interface/efi/efi_entry.c b/src/interface/efi/efi_entry.c
index b00828ad..7b670f8e 100644
--- a/src/interface/efi/efi_entry.c
+++ b/src/interface/efi/efi_entry.c
@@ -17,6 +17,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <gpxe/efi/efi.h>
#include <gpxe/uuid.h>
@@ -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
*
@@ -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 */
@@ -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() */