Преглед на файлове

[efi] Allow use of EFI configuration tables

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.
tags/v0.9.7
Michael Brown преди 16 години
родител
ревизия
045a22764a
променени са 2 файла, в които са добавени 78 реда и са изтрити 4 реда
  1. 33
    0
      src/include/gpxe/efi/efi.h
  2. 45
    4
      src/interface/efi/efi_entry.c

+ 33
- 0
src/include/gpxe/efi/efi.h Целия файл

@@ -43,6 +43,7 @@
43 43
 
44 44
 /** An EFI protocol used by gPXE */
45 45
 struct efi_protocol {
46
+	/** GUID */
46 47
 	union {
47 48
 		/** EFI protocol GUID */
48 49
 		EFI_GUID guid;
@@ -70,6 +71,38 @@ struct efi_protocol {
70 71
 				(_ptr) : (_ptr) ) ),			     \
71 72
 	}
72 73
 
74
+/** An EFI configuration table used by gPXE */
75
+struct efi_config_table {
76
+	/** GUID */
77
+	union {
78
+		/** EFI configuration table GUID */
79
+		EFI_GUID guid;
80
+		/** UUID structure understood by gPXE */
81
+		union uuid uuid;
82
+	} u;
83
+	/** Variable containing pointer to configuration table */
84
+	void **table;
85
+	/** Table is required for operation */
86
+	int required;
87
+};
88
+
89
+/** Declare an EFI configuration table used by gPXE */
90
+#define __efi_config_table \
91
+	__table ( struct efi_config_table, efi_config_tables, 01 )
92
+
93
+/** Declare an EFI configuration table to be used by gPXE
94
+ *
95
+ * @v _table		EFI configuration table name
96
+ * @v _ptr		Pointer to configuration table
97
+ * @v _required		Table is required for operation
98
+ */
99
+#define EFI_USE_TABLE( _table, _ptr, _required )			     \
100
+	struct efi_config_table __ ## _table __efi_config_table = {	     \
101
+		.u.guid = _table ## _GUID,				     \
102
+		.table = ( ( void ** ) ( void * ) (_ptr) ),		     \
103
+		.required = (_required),				     \
104
+	}
105
+
73 106
 /** Convert a gPXE status code to an EFI status code
74 107
  *
75 108
  * FIXME: actually perform some kind of conversion.  gPXE error codes

+ 45
- 4
src/interface/efi/efi_entry.c Целия файл

@@ -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() */

Loading…
Отказ
Запис