Changeset View
Changeset View
Standalone View
Standalone View
head/sys/boot/efi/loader/main.c
Show All 22 Lines | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | |||||
#include <stand.h> | #include <stand.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <setjmp.h> | #include <setjmp.h> | ||||
#include <efi.h> | #include <efi.h> | ||||
#include <efilib.h> | #include <efilib.h> | ||||
#include <bootstrap.h> | #include <bootstrap.h> | ||||
#include <smbios.h> | #include <smbios.h> | ||||
#include "loader_efi.h" | #include "loader_efi.h" | ||||
extern char bootprog_name[]; | extern char bootprog_name[]; | ||||
extern char bootprog_rev[]; | extern char bootprog_rev[]; | ||||
extern char bootprog_date[]; | extern char bootprog_date[]; | ||||
extern char bootprog_maker[]; | extern char bootprog_maker[]; | ||||
struct devdesc currdev; /* our current device */ | |||||
struct arch_switch archsw; /* MI/MD interface boundary */ | struct arch_switch archsw; /* MI/MD interface boundary */ | ||||
EFI_GUID acpi = ACPI_TABLE_GUID; | EFI_GUID acpi = ACPI_TABLE_GUID; | ||||
EFI_GUID acpi20 = ACPI_20_TABLE_GUID; | EFI_GUID acpi20 = ACPI_20_TABLE_GUID; | ||||
EFI_GUID devid = DEVICE_PATH_PROTOCOL; | EFI_GUID devid = DEVICE_PATH_PROTOCOL; | ||||
EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; | EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; | ||||
EFI_GUID mps = MPS_TABLE_GUID; | EFI_GUID mps = MPS_TABLE_GUID; | ||||
EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; | EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; | ||||
EFI_GUID smbios = SMBIOS_TABLE_GUID; | EFI_GUID smbios = SMBIOS_TABLE_GUID; | ||||
EFI_GUID dxe = DXE_SERVICES_TABLE_GUID; | EFI_GUID dxe = DXE_SERVICES_TABLE_GUID; | ||||
EFI_GUID hoblist = HOB_LIST_TABLE_GUID; | EFI_GUID hoblist = HOB_LIST_TABLE_GUID; | ||||
EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; | EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; | ||||
EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; | EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; | ||||
EFI_GUID fdtdtb = FDT_TABLE_GUID; | EFI_GUID fdtdtb = FDT_TABLE_GUID; | ||||
/* | |||||
* Need this because EFI uses UTF-16 unicode string constants, but we | |||||
* use UTF-8. We can't use printf due to the possiblity of \0 and we | |||||
* don't support support wide characters either. | |||||
*/ | |||||
static void | |||||
print_str16(const CHAR16 *str) | |||||
{ | |||||
int i; | |||||
for (i = 0; str[i]; i++) | |||||
printf("%c", (char)str[i]); | |||||
} | |||||
EFI_STATUS | EFI_STATUS | ||||
main(int argc, CHAR16 *argv[]) | main(int argc, CHAR16 *argv[]) | ||||
{ | { | ||||
char var[128]; | char var[128]; | ||||
EFI_LOADED_IMAGE *img; | EFI_LOADED_IMAGE *img; | ||||
EFI_GUID *guid; | EFI_GUID *guid; | ||||
int i, j, vargood; | int i, j, vargood, unit; | ||||
struct devsw *dev; | |||||
UINTN k; | UINTN k; | ||||
archsw.arch_autoload = efi_autoload; | |||||
archsw.arch_getdev = efi_getdev; | |||||
archsw.arch_copyin = efi_copyin; | |||||
archsw.arch_copyout = efi_copyout; | |||||
archsw.arch_readin = efi_readin; | |||||
/* | /* | ||||
* XXX Chicken-and-egg problem; we want to have console output | * XXX Chicken-and-egg problem; we want to have console output | ||||
* early, but some console attributes may depend on reading from | * early, but some console attributes may depend on reading from | ||||
* eg. the boot device, which we can't do yet. We can use | * eg. the boot device, which we can't do yet. We can use | ||||
* printf() etc. once this is done. | * printf() etc. once this is done. | ||||
*/ | */ | ||||
cons_probe(); | cons_probe(); | ||||
Show All 30 Lines | main(int argc, CHAR16 *argv[]) | ||||
*/ | */ | ||||
for (i = 0; devsw[i] != NULL; i++) | for (i = 0; devsw[i] != NULL; i++) | ||||
if (devsw[i]->dv_init != NULL) | if (devsw[i]->dv_init != NULL) | ||||
(devsw[i]->dv_init)(); | (devsw[i]->dv_init)(); | ||||
/* Get our loaded image protocol interface structure. */ | /* Get our loaded image protocol interface structure. */ | ||||
BS->HandleProtocol(IH, &imgid, (VOID**)&img); | BS->HandleProtocol(IH, &imgid, (VOID**)&img); | ||||
printf("Command line arguments:"); | |||||
for (i = 0; i < argc; i++) { | |||||
printf(" "); | |||||
print_str16(argv[i]); | |||||
} | |||||
printf("\n"); | |||||
printf("Image base: 0x%lx\n", (u_long)img->ImageBase); | printf("Image base: 0x%lx\n", (u_long)img->ImageBase); | ||||
printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16, | printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16, | ||||
ST->Hdr.Revision & 0xffff); | ST->Hdr.Revision & 0xffff); | ||||
printf("EFI Firmware: "); | printf("EFI Firmware: "); | ||||
/* printf doesn't understand EFI Unicode */ | /* printf doesn't understand EFI Unicode */ | ||||
ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor); | ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor); | ||||
printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16, | printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16, | ||||
ST->FirmwareRevision & 0xffff); | ST->FirmwareRevision & 0xffff); | ||||
printf("\n"); | printf("\n"); | ||||
printf("%s, Revision %s\n", bootprog_name, bootprog_rev); | printf("%s, Revision %s\n", bootprog_name, bootprog_rev); | ||||
printf("(%s, %s)\n", bootprog_maker, bootprog_date); | printf("(%s, %s)\n", bootprog_maker, bootprog_date); | ||||
efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit); | |||||
currdev.d_type = currdev.d_dev->dv_type; | |||||
/* | /* | ||||
* Disable the watchdog timer. By default the boot manager sets | * Disable the watchdog timer. By default the boot manager sets | ||||
* the timer to 5 minutes before invoking a boot option. If we | * the timer to 5 minutes before invoking a boot option. If we | ||||
* want to return to the boot manager, we have to disable the | * want to return to the boot manager, we have to disable the | ||||
* watchdog timer and since we're an interactive program, we don't | * watchdog timer and since we're an interactive program, we don't | ||||
* want to wait until the user types "quit". The timer may have | * want to wait until the user types "quit". The timer may have | ||||
* fired by then. We don't care if this fails. It does not prevent | * fired by then. We don't care if this fails. It does not prevent | ||||
* normal functioning in any way... | * normal functioning in any way... | ||||
*/ | */ | ||||
BS->SetWatchdogTimer(0, 0, 0, NULL); | BS->SetWatchdogTimer(0, 0, 0, NULL); | ||||
if (efi_handle_lookup(img->DeviceHandle, &dev, &unit) != 0) | |||||
return (EFI_NOT_FOUND); | |||||
switch (dev->dv_type) { | |||||
default: { | |||||
struct devdesc currdev; | |||||
currdev.d_dev = dev; | |||||
currdev.d_unit = unit; | |||||
currdev.d_opendata = NULL; | |||||
currdev.d_type = currdev.d_dev->dv_type; | |||||
env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), | env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), | ||||
efi_setcurrdev, env_nounset); | efi_setcurrdev, env_nounset); | ||||
env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, | env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, | ||||
env_nounset); | env_nounset); | ||||
break; | |||||
} | |||||
} | |||||
setenv("LINES", "24", 1); /* optional */ | setenv("LINES", "24", 1); /* optional */ | ||||
archsw.arch_autoload = efi_autoload; | |||||
archsw.arch_getdev = efi_getdev; | |||||
archsw.arch_copyin = efi_copyin; | |||||
archsw.arch_copyout = efi_copyout; | |||||
archsw.arch_readin = efi_readin; | |||||
for (k = 0; k < ST->NumberOfTableEntries; k++) { | for (k = 0; k < ST->NumberOfTableEntries; k++) { | ||||
guid = &ST->ConfigurationTable[k].VendorGuid; | guid = &ST->ConfigurationTable[k].VendorGuid; | ||||
if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) { | if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) { | ||||
smbios_detect(ST->ConfigurationTable[k].VendorTable); | smbios_detect(ST->ConfigurationTable[k].VendorTable); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 278 Lines • Show Last 20 Lines |