diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -455,36 +455,25 @@ } } +/* + * Handle the EFI memory map list. + * + * We will make two passes at this, the first (exclude == false) to populate + * physmem with valid physical memory ranges from recognized map entry types. + * In the second pass we will exclude memory ranges from physmem which must not + * be used for general allocations, either because they are used by runtime + * firmware or otherwise reserved. + * + * Adding the runtime-reserved memory ranges to physmem and excluding them + * later ensures that they are included in the DMAP, but excluded from + * phys_avail[]. + * + * Entry types not explicitly listed here are ignored and not mapped. + */ static void -exclude_efi_map_entry(struct efi_md *p, void *argp __unused) -{ - - switch (p->md_type) { - case EFI_MD_TYPE_CODE: - case EFI_MD_TYPE_DATA: - case EFI_MD_TYPE_BS_CODE: - case EFI_MD_TYPE_BS_DATA: - case EFI_MD_TYPE_FREE: - /* - * We're allowed to use any entry with these types. - */ - break; - default: - physmem_exclude_region(p->md_phys, p->md_pages * EFI_PAGE_SIZE, - EXFLAG_NOALLOC); - } -} - -static void -exclude_efi_map_entries(struct efi_map_header *efihdr) -{ - - foreach_efi_map_entry(efihdr, exclude_efi_map_entry, NULL); -} - -static void -add_efi_map_entry(struct efi_md *p, void *argp __unused) +handle_efi_map_entry(struct efi_md *p, void *argp) { + bool exclude = *(bool *)argp; switch (p->md_type) { case EFI_MD_TYPE_RECLAIM: @@ -496,7 +485,7 @@ /* * Some UEFI implementations put the system table in the * runtime code section. Include it in the DMAP, but will - * be excluded from phys_avail later. + * be excluded from phys_avail. */ case EFI_MD_TYPE_RT_DATA: /* @@ -504,6 +493,12 @@ * region is created to stop it from being added * to phys_avail. */ + if (exclude) { + physmem_exclude_region(p->md_phys, + p->md_pages * EFI_PAGE_SIZE, EXFLAG_NOALLOC); + break; + } + /* FALLTHROUGH */ case EFI_MD_TYPE_CODE: case EFI_MD_TYPE_DATA: case EFI_MD_TYPE_BS_CODE: @@ -512,8 +507,12 @@ /* * We're allowed to use any entry with these types. */ - physmem_hardware_region(p->md_phys, - p->md_pages * EFI_PAGE_SIZE); + if (!exclude) + physmem_hardware_region(p->md_phys, + p->md_pages * EFI_PAGE_SIZE); + break; + default: + /* Other types shall not be handled by physmem. */ break; } } @@ -521,7 +520,15 @@ static void add_efi_map_entries(struct efi_map_header *efihdr) { - foreach_efi_map_entry(efihdr, add_efi_map_entry, NULL); + bool exclude = false; + foreach_efi_map_entry(efihdr, handle_efi_map_entry, &exclude); +} + +static void +exclude_efi_map_entries(struct efi_map_header *efihdr) +{ + bool exclude = true; + foreach_efi_map_entry(efihdr, handle_efi_map_entry, &exclude); } static void