|  | @@ -17,6 +17,7 @@
 | 
		
	
		
			
			| 17 | 17 |   */
 | 
		
	
		
			
			| 18 | 18 |  
 | 
		
	
		
			
			| 19 | 19 |  #include <stdlib.h>
 | 
		
	
		
			
			|  | 20 | +#include <string.h>
 | 
		
	
		
			
			| 20 | 21 |  #include <gpxe/efi/efi.h>
 | 
		
	
		
			
			| 21 | 22 |  #include <gpxe/uuid.h>
 | 
		
	
		
			
			| 22 | 23 |  
 | 
		
	
	
		
			
			|  | @@ -32,6 +33,30 @@ static struct efi_protocol efi_protocols[0] \
 | 
		
	
		
			
			| 32 | 33 |  static struct efi_protocol efi_protocols_end[0] \
 | 
		
	
		
			
			| 33 | 34 |  	__table_end ( struct efi_protocol, efi_protocols );
 | 
		
	
		
			
			| 34 | 35 |  
 | 
		
	
		
			
			|  | 36 | +/** Declared used EFI configuration tables */
 | 
		
	
		
			
			|  | 37 | +static struct efi_config_table efi_config_tables[0] \
 | 
		
	
		
			
			|  | 38 | +	__table_start ( struct efi_config_table, efi_config_tables );
 | 
		
	
		
			
			|  | 39 | +static struct efi_config_table efi_config_tables_end[0] \
 | 
		
	
		
			
			|  | 40 | +	__table_end ( struct efi_config_table, efi_config_tables );
 | 
		
	
		
			
			|  | 41 | +
 | 
		
	
		
			
			|  | 42 | +/**
 | 
		
	
		
			
			|  | 43 | + * Look up EFI configuration table
 | 
		
	
		
			
			|  | 44 | + *
 | 
		
	
		
			
			|  | 45 | + * @v guid		Configuration table GUID
 | 
		
	
		
			
			|  | 46 | + * @ret table		Configuration table, or NULL
 | 
		
	
		
			
			|  | 47 | + */
 | 
		
	
		
			
			|  | 48 | +static void * efi_find_table ( EFI_GUID *guid ) {
 | 
		
	
		
			
			|  | 49 | +	unsigned int i;
 | 
		
	
		
			
			|  | 50 | +
 | 
		
	
		
			
			|  | 51 | +	for ( i = 0 ; i < efi_systab->NumberOfTableEntries ; i++ ) {
 | 
		
	
		
			
			|  | 52 | +		if ( memcmp ( &efi_systab->ConfigurationTable[i].VendorGuid,
 | 
		
	
		
			
			|  | 53 | +			      guid, sizeof ( *guid ) ) == 0 )
 | 
		
	
		
			
			|  | 54 | +			return efi_systab->ConfigurationTable[i].VendorTable;
 | 
		
	
		
			
			|  | 55 | +	}
 | 
		
	
		
			
			|  | 56 | +
 | 
		
	
		
			
			|  | 57 | +	return NULL;
 | 
		
	
		
			
			|  | 58 | +}
 | 
		
	
		
			
			|  | 59 | +
 | 
		
	
		
			
			| 35 | 60 |  /**
 | 
		
	
		
			
			| 36 | 61 |   * EFI entry point
 | 
		
	
		
			
			| 37 | 62 |   *
 | 
		
	
	
		
			
			|  | @@ -43,6 +68,7 @@ EFI_STATUS EFIAPI efi_entry ( EFI_HANDLE image_handle,
 | 
		
	
		
			
			| 43 | 68 |  			      EFI_SYSTEM_TABLE *systab ) {
 | 
		
	
		
			
			| 44 | 69 |  	EFI_BOOT_SERVICES *bs;
 | 
		
	
		
			
			| 45 | 70 |  	struct efi_protocol *prot;
 | 
		
	
		
			
			|  | 71 | +	struct efi_config_table *tab;
 | 
		
	
		
			
			| 46 | 72 |  	EFI_STATUS efirc;
 | 
		
	
		
			
			| 47 | 73 |  
 | 
		
	
		
			
			| 48 | 74 |  	/* Store image handle and system table pointer for future use */
 | 
		
	
	
		
			
			|  | @@ -65,17 +91,32 @@ EFI_STATUS EFIAPI efi_entry ( EFI_HANDLE image_handle,
 | 
		
	
		
			
			| 65 | 91 |  	}
 | 
		
	
		
			
			| 66 | 92 |  	DBGC ( systab, "EFI handle %p systab %p\n", image_handle, systab );
 | 
		
	
		
			
			| 67 | 93 |  
 | 
		
	
		
			
			| 68 |  | -	/* Look up required protocols */
 | 
		
	
		
			
			|  | 94 | +	/* Look up used protocols */
 | 
		
	
		
			
			| 69 | 95 |  	bs = systab->BootServices;
 | 
		
	
		
			
			| 70 | 96 |  	for ( prot = efi_protocols ; prot < efi_protocols_end ; prot++ ) {
 | 
		
	
		
			
			| 71 | 97 |  		if ( ( efirc = bs->LocateProtocol ( &prot->u.guid, NULL,
 | 
		
	
		
			
			| 72 |  | -						    prot->protocol ) ) != 0 ) {
 | 
		
	
		
			
			|  | 98 | +						    prot->protocol ) ) == 0 ) {
 | 
		
	
		
			
			|  | 99 | +			DBGC ( systab, "EFI protocol %s is at %p\n",
 | 
		
	
		
			
			|  | 100 | +			       uuid_ntoa ( &prot->u.uuid ), *(prot->protocol));
 | 
		
	
		
			
			|  | 101 | +		} else {
 | 
		
	
		
			
			| 73 | 102 |  			DBGC ( systab, "EFI does not provide protocol %s\n",
 | 
		
	
		
			
			| 74 | 103 |  			       uuid_ntoa ( &prot->u.uuid ) );
 | 
		
	
		
			
			|  | 104 | +			/* All protocols are required */
 | 
		
	
		
			
			| 75 | 105 |  			return efirc;
 | 
		
	
		
			
			| 76 | 106 |  		}
 | 
		
	
		
			
			| 77 |  | -		DBGC ( systab, "EFI protocol %s is at %p\n",
 | 
		
	
		
			
			| 78 |  | -		       uuid_ntoa ( &prot->u.uuid ), *(prot->protocol) );
 | 
		
	
		
			
			|  | 107 | +	}
 | 
		
	
		
			
			|  | 108 | +
 | 
		
	
		
			
			|  | 109 | +	/* Look up used configuration tables */
 | 
		
	
		
			
			|  | 110 | +	for ( tab = efi_config_tables ; tab < efi_config_tables_end ; tab++ ) {
 | 
		
	
		
			
			|  | 111 | +		if ( ( *(tab->table) = efi_find_table ( &tab->u.guid ) ) ) {
 | 
		
	
		
			
			|  | 112 | +			DBGC ( systab, "EFI configuration table %s is at %p\n",
 | 
		
	
		
			
			|  | 113 | +			       uuid_ntoa ( &tab->u.uuid ), *(tab->table) );
 | 
		
	
		
			
			|  | 114 | +		} else {
 | 
		
	
		
			
			|  | 115 | +			DBGC ( systab, "EFI does not provide configuration "
 | 
		
	
		
			
			|  | 116 | +			       "table %s\n", uuid_ntoa ( &tab->u.uuid ) );
 | 
		
	
		
			
			|  | 117 | +			if ( tab->required )
 | 
		
	
		
			
			|  | 118 | +				return EFI_NOT_AVAILABLE_YET;
 | 
		
	
		
			
			|  | 119 | +		}
 | 
		
	
		
			
			| 79 | 120 |  	}
 | 
		
	
		
			
			| 80 | 121 |  
 | 
		
	
		
			
			| 81 | 122 |  	/* Call to main() */
 |