Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/efidev/efirt.c
Show First 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | efi_is_in_map(struct efi_md *map, int ndesc, int descsz, vm_offset_t addr) | ||||
return (false); | return (false); | ||||
} | } | ||||
static int | static int | ||||
efi_init(void) | efi_init(void) | ||||
{ | { | ||||
struct efi_map_header *efihdr; | struct efi_map_header *efihdr; | ||||
struct efi_md *map; | struct efi_md *map; | ||||
struct efi_rt *rtdm; | |||||
caddr_t kmdp; | caddr_t kmdp; | ||||
size_t efisz; | size_t efisz; | ||||
int rt_disabled; | int ndesc, rt_disabled; | ||||
rt_disabled = 0; | rt_disabled = 0; | ||||
TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled); | TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled); | ||||
if (rt_disabled == 1) | if (rt_disabled == 1) | ||||
return (0); | return (0); | ||||
mtx_init(&efi_lock, "efi", NULL, MTX_DEF); | mtx_init(&efi_lock, "efi", NULL, MTX_DEF); | ||||
if (efi_systbl_phys == 0) { | if (efi_systbl_phys == 0) { | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("EFI systbl not available\n"); | printf("EFI systbl not available\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (!PMAP_HAS_DMAP) { | |||||
if (bootverbose) | efi_systbl = (struct efi_systbl *)efi_phys_to_kva(efi_systbl_phys); | ||||
printf("EFI systbl requires direct map\n"); | if (efi_systbl == NULL || efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { | ||||
return (0); | |||||
} | |||||
efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys); | |||||
if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { | |||||
efi_systbl = NULL; | efi_systbl = NULL; | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("EFI systbl signature invalid\n"); | printf("EFI systbl signature invalid\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL : | efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL : | ||||
(struct efi_cfgtbl *)efi_systbl->st_cfgtbl; | (struct efi_cfgtbl *)efi_systbl->st_cfgtbl; | ||||
if (efi_cfgtbl == NULL) { | if (efi_cfgtbl == NULL) { | ||||
Show All 11 Lines | if (bootverbose) | ||||
printf("EFI map is not present\n"); | printf("EFI map is not present\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; | efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; | ||||
map = (struct efi_md *)((uint8_t *)efihdr + efisz); | map = (struct efi_md *)((uint8_t *)efihdr + efisz); | ||||
if (efihdr->descriptor_size == 0) | if (efihdr->descriptor_size == 0) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
if (!efi_create_1t1_map(map, efihdr->memory_size / | ndesc = efihdr->memory_size / efihdr->descriptor_size; | ||||
efihdr->descriptor_size, efihdr->descriptor_size)) { | if (!efi_create_1t1_map(map, ndesc, efihdr->descriptor_size)) { | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("EFI cannot create runtime map\n"); | printf("EFI cannot create runtime map\n"); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
efi_runtime = (efi_systbl->st_rt == 0) ? NULL : | efi_runtime = (efi_systbl->st_rt == 0) ? NULL : | ||||
(struct efi_rt *)efi_systbl->st_rt; | (struct efi_rt *)efi_systbl->st_rt; | ||||
if (efi_runtime == NULL) { | if (efi_runtime == NULL) { | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("EFI runtime services table is not present\n"); | printf("EFI runtime services table is not present\n"); | ||||
efi_destroy_1t1_map(); | efi_destroy_1t1_map(); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
#if defined(__aarch64__) || defined(__amd64__) | |||||
/* | /* | ||||
* Some UEFI implementations have multiple implementations of the | * Some UEFI implementations have multiple implementations of the | ||||
* RS->GetTime function. They switch from one we can only use early | * RS->GetTime function. They switch from one we can only use early | ||||
* in the boot process to one valid as a RunTime service only when we | * in the boot process to one valid as a RunTime service only when we | ||||
* call RS->SetVirtualAddressMap. As this is not always the case, e.g. | * call RS->SetVirtualAddressMap. As this is not always the case, e.g. | ||||
* with an old loader.efi, check if the RS->GetTime function is within | * with an old loader.efi, check if the RS->GetTime function is within | ||||
* the EFI map, and fail to attach if not. | * the EFI map, and fail to attach if not. | ||||
* | |||||
* We need to enter into the EFI environment as efi_runtime may point | |||||
* to an EFI address. | |||||
*/ | */ | ||||
efi_enter(); | rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime); | ||||
if (!efi_is_in_map(map, efihdr->memory_size / efihdr->descriptor_size, | if (rtdm == NULL || !efi_is_in_map(map, ndesc, efihdr->descriptor_size, | ||||
efihdr->descriptor_size, (vm_offset_t)efi_runtime->rt_gettime)) { | (vm_offset_t)rtdm->rt_gettime)) { | ||||
efi_leave(); | |||||
if (bootverbose) | if (bootverbose) | ||||
printf( | printf( | ||||
"EFI runtime services table has an invalid pointer\n"); | "EFI runtime services table has an invalid pointer\n"); | ||||
efi_runtime = NULL; | efi_runtime = NULL; | ||||
efi_destroy_1t1_map(); | efi_destroy_1t1_map(); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
efi_leave(); | #endif | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
efi_uninit(void) | efi_uninit(void) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | efi_get_table(struct uuid *uuid, void **ptr) | ||||
u_long count; | u_long count; | ||||
if (efi_cfgtbl == NULL || efi_systbl == NULL) | if (efi_cfgtbl == NULL || efi_systbl == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
count = efi_systbl->st_entries; | count = efi_systbl->st_entries; | ||||
ct = efi_cfgtbl; | ct = efi_cfgtbl; | ||||
while (count--) { | while (count--) { | ||||
if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { | if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { | ||||
*ptr = (void *)PHYS_TO_DMAP(ct->ct_data); | *ptr = efi_phys_to_kva(ct->ct_data); | ||||
return (0); | return (0); | ||||
} | } | ||||
ct++; | ct++; | ||||
} | } | ||||
return (ENOENT); | return (ENOENT); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 166 Lines • Show Last 20 Lines |