iPXE
efi_table.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <assert.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <ipxe/efi/efi.h>
30 #include <ipxe/efi/efi_table.h>
31 
32 /** @file
33  *
34  * EFI configuration tables
35  *
36  */
37 
38 /**
39  * Look up EFI configuration table
40  *
41  * @v guid Configuration table GUID
42  * @ret table Configuration table, or NULL
43  */
45  void *table;
46  unsigned int i;
47 
48  /* Scan for installed table */
49  for ( i = 0 ; i < efi_systab->NumberOfTableEntries ; i++ ) {
51  guid, sizeof ( *guid ) ) == 0 ) {
53  DBGC ( guid, "EFITAB %s is at %p\n",
54  efi_guid_ntoa ( guid ), table );
55  return table;
56  }
57  }
58 
59  return NULL;
60 }
61 
62 /**
63  * Install EFI configuration table
64  *
65  * @v table Configuration table type
66  * @v data Configuration table data, or NULL to uninstall
67  * @v backup Table backup, or NULL to not back up old table
68  * @ret rc Return status code
69  */
70 int efi_install_table ( struct efi_table *table, const void *data,
71  void **backup ) {
73  EFI_GUID *guid = table->guid;
74  void *copy;
75  void *new;
76  void *old;
77  size_t old_len;
78  size_t new_len;
79  EFI_STATUS efirc;
80  int rc;
81 
82  /* Get currently installed table, if any */
83  old = efi_find_table ( guid );
84  old_len = ( old ? table->len ( old ) : 0 );
85 
86  /* Create backup copy, if applicable */
87  if ( old_len && backup ) {
88  if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, old_len,
89  &copy ) ) != 0 ) {
90  rc = -EEFI ( efirc );
91  goto err_backup;
92  }
93  memcpy ( copy, old, old_len );
94  DBGC ( table, "EFITAB %s %p+%#zx backed up\n",
95  efi_guid_ntoa ( guid ), old, old_len );
96  } else {
97  copy = NULL;
98  }
99 
100  /* Create installable runtime services data copy, if applicable */
101  new_len = ( data ? table->len ( data ) : 0 );
102  if ( new_len ) {
103  if ( ( efirc = bs->AllocatePool ( EfiRuntimeServicesData,
104  new_len, &new ) ) != 0 ) {
105  rc = -EEFI ( efirc );
106  goto err_allocate;
107  }
108  memcpy ( new, data, new_len );
109  } else {
110  new = NULL;
111  }
112 
113  /* (Un)install configuration table, if applicable */
114  if ( new || old ) {
115  if ( ( efirc = bs->InstallConfigurationTable ( guid,
116  new ) ) != 0 ) {
117  rc = -EEFI ( efirc );
118  DBGC ( table, "EFITAB %s could not install: %s\n",
119  efi_guid_ntoa ( guid ), strerror ( rc ) );
120  goto err_install;
121  }
122  if ( old ) {
123  DBGC ( table, "EFITAB %s %p+%#zx uninstalled\n",
124  efi_guid_ntoa ( guid ), old, old_len );
125  }
126  if ( new ) {
127  DBGC ( table, "EFITAB %s %p+%#zx installed\n",
128  efi_guid_ntoa ( guid ), new, new_len );
129  }
130  }
131 
132  /* Record backup copy, if applicable */
133  if ( backup ) {
134  if ( *backup )
135  bs->FreePool ( *backup );
136  *backup = copy;
137  }
138 
139  /* Sanity check */
140  assert ( efi_find_table ( guid ) == new );
141 
142  return 0;
143 
144  err_install:
145  if ( new )
146  bs->FreePool ( new );
147  err_allocate:
148  if ( copy )
149  bs->FreePool ( copy );
150  err_backup:
151  return rc;
152 }
153 
154 /**
155  * Uninstall EFI configuration table
156  *
157  * @v table Configuration table type
158  * @v backup Table backup (or NULL to not restore old table)
159  * @ret rc Return status code
160  */
161 int efi_uninstall_table ( struct efi_table *table, void **backup ) {
163  void *old;
164  int rc;
165 
166  /* Uninstall or reinstall as applicable */
167  old = ( backup ? *backup : NULL );
168  if ( ( rc = efi_install_table ( table, old, NULL ) ) != 0 )
169  return rc;
170 
171  /* Free backup copy, if applicable */
172  if ( backup && *backup ) {
173  bs->FreePool ( *backup );
174  *backup = NULL;
175  }
176 
177  return 0;
178 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2098
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:174
128 bit buffer containing a unique identifier value.
Definition: Base.h:215
Error codes.
EFI_GUID VendorGuid
The 128-bit GUID value that uniquely identifies the system configuration table.
Definition: UefiSpec.h:2033
#define DBGC(...)
Definition: compiler.h:505
int old
Definition: bitops.h:64
An installable EFI configuration table type.
Definition: efi_table.h:15
size_t(* len)(const void *data)
Determine length of table.
Definition: efi_table.h:29
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI configuration tables.
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1930
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_guid.c:725
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1949
EFI API.
uint64_t guid
GUID.
Definition: edd.h:30
int efi_uninstall_table(struct efi_table *table, void **backup)
Uninstall EFI configuration table.
Definition: efi_table.c:161
The data portions of a loaded Runtime Services Driver and the default data allocation type used by a ...
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
UINTN NumberOfTableEntries
The number of system configuration tables in the buffer ConfigurationTable.
Definition: UefiSpec.h:2102
uint8_t data[48]
Additional event data.
Definition: ena.h:22
EFI_SYSTEM_TABLE * efi_systab
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
EFI_GUID * guid
Table GUID.
Definition: efi_table.h:17
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
void * efi_find_table(EFI_GUID *guid)
Look up EFI configuration table.
Definition: efi_table.c:44
EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable
Definition: UefiSpec.h:1972
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1948
EFI_CONFIGURATION_TABLE * ConfigurationTable
A pointer to the system configuration tables.
Definition: UefiSpec.h:2107
int efi_install_table(struct efi_table *table, const void *data, void **backup)
Install EFI configuration table.
Definition: efi_table.c:70
VOID * VendorTable
A pointer to the table associated with VendorGuid.
Definition: UefiSpec.h:2037