1 /* 2 * Copyright (C) 2008 Michael Brown <mbrown (at) 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., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <string.h> 22 #include <gpxe/efi/efi.h> 23 #include <gpxe/uuid.h> 24 25 /** Image handle passed to entry point */ 26 EFI_HANDLE efi_image_handle; 27 28 /** System table passed to entry point */ 29 EFI_SYSTEM_TABLE *efi_systab; 30 31 /** 32 * Look up EFI configuration table 33 * 34 * @v guid Configuration table GUID 35 * @ret table Configuration table, or NULL 36 */ 37 static void * efi_find_table ( EFI_GUID *guid ) { 38 unsigned int i; 39 40 for ( i = 0 ; i < efi_systab->NumberOfTableEntries ; i++ ) { 41 if ( memcmp ( &efi_systab->ConfigurationTable[i].VendorGuid, 42 guid, sizeof ( *guid ) ) == 0 ) 43 return efi_systab->ConfigurationTable[i].VendorTable; 44 } 45 46 return NULL; 47 } 48 49 /** 50 * Initialise EFI environment 51 * 52 * @v image_handle Image handle 53 * @v systab System table 54 * @ret efirc EFI return status code 55 */ 56 EFI_STATUS efi_init ( EFI_HANDLE image_handle, 57 EFI_SYSTEM_TABLE *systab ) { 58 EFI_BOOT_SERVICES *bs; 59 struct efi_protocol *prot; 60 struct efi_config_table *tab; 61 EFI_STATUS efirc; 62 63 /* Store image handle and system table pointer for future use */ 64 efi_image_handle = image_handle; 65 efi_systab = systab; 66 67 /* Sanity checks */ 68 if ( ! systab ) 69 return EFI_NOT_AVAILABLE_YET; 70 if ( ! systab->ConOut ) 71 return EFI_NOT_AVAILABLE_YET; 72 if ( ! systab->BootServices ) { 73 DBGC ( systab, "EFI provided no BootServices entry point\n" ); 74 return EFI_NOT_AVAILABLE_YET; 75 } 76 if ( ! systab->RuntimeServices ) { 77 DBGC ( systab, "EFI provided no RuntimeServices entry " 78 "point\n" ); 79 return EFI_NOT_AVAILABLE_YET; 80 } 81 DBGC ( systab, "EFI handle %p systab %p\n", image_handle, systab ); 82 83 /* Look up used protocols */ 84 bs = systab->BootServices; 85 for_each_table_entry ( prot, EFI_PROTOCOLS ) { 86 if ( ( efirc = bs->LocateProtocol ( &prot->u.guid, NULL, 87 prot->protocol ) ) == 0 ) { 88 DBGC ( systab, "EFI protocol %s is at %p\n", 89 uuid_ntoa ( &prot->u.uuid ), *(prot->protocol)); 90 } else { 91 DBGC ( systab, "EFI does not provide protocol %s\n", 92 uuid_ntoa ( &prot->u.uuid ) ); 93 /* All protocols are required */ 94 return efirc; 95 } 96 } 97 98 /* Look up used configuration tables */ 99 for_each_table_entry ( tab, EFI_CONFIG_TABLES ) { 100 if ( ( *(tab->table) = efi_find_table ( &tab->u.guid ) ) ) { 101 DBGC ( systab, "EFI configuration table %s is at %p\n", 102 uuid_ntoa ( &tab->u.uuid ), *(tab->table) ); 103 } else { 104 DBGC ( systab, "EFI does not provide configuration " 105 "table %s\n", uuid_ntoa ( &tab->u.uuid ) ); 106 if ( tab->required ) 107 return EFI_NOT_AVAILABLE_YET; 108 } 109 } 110 111 return 0; 112 } 113