#include <sys/param.h>
#include <sys/systm.h>
#include <sys/efi.h>
#include <sys/efi_map.h>
#include <sys/physmem.h>
#include <machine/efi.h>
#include <machine/vmparam.h>
void
efi_map_foreach_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp)
{
struct efi_md *map, *p;
size_t efisz;
int ndesc, i;
efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
map = (struct efi_md *)((uint8_t *)efihdr + efisz);
if (efihdr->descriptor_size == 0)
return;
ndesc = efihdr->memory_size / efihdr->descriptor_size;
for (i = 0, p = map; i < ndesc; i++,
p = efi_next_descriptor(p, efihdr->descriptor_size)) {
cb(p, argp);
}
}
static void
handle_efi_map_entry(struct efi_md *p, void *argp)
{
bool exclude = *(bool *)argp;
switch (p->md_type) {
case EFI_MD_TYPE_RECLAIM:
case EFI_MD_TYPE_RT_CODE:
case EFI_MD_TYPE_RT_DATA:
if (exclude) {
physmem_exclude_region(p->md_phys,
p->md_pages * EFI_PAGE_SIZE, EXFLAG_NOALLOC);
break;
}
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:
if (!exclude)
physmem_hardware_region(p->md_phys,
p->md_pages * EFI_PAGE_SIZE);
break;
default:
break;
}
}
void
efi_map_add_entries(struct efi_map_header *efihdr)
{
bool exclude = false;
efi_map_foreach_entry(efihdr, handle_efi_map_entry, &exclude);
}
void
efi_map_exclude_entries(struct efi_map_header *efihdr)
{
bool exclude = true;
efi_map_foreach_entry(efihdr, handle_efi_map_entry, &exclude);
}
static void
print_efi_map_entry(struct efi_md *p, void *argp __unused)
{
const char *type;
static const char *types[] = {
"Reserved",
"LoaderCode",
"LoaderData",
"BootServicesCode",
"BootServicesData",
"RuntimeServicesCode",
"RuntimeServicesData",
"ConventionalMemory",
"UnusableMemory",
"ACPIReclaimMemory",
"ACPIMemoryNVS",
"MemoryMappedIO",
"MemoryMappedIOPortSpace",
"PalCode",
"PersistentMemory"
};
if (p->md_type < nitems(types))
type = types[p->md_type];
else
type = "<INVALID>";
printf("%23s %012jx %012jx %08jx ", type, (uintmax_t)p->md_phys,
(uintmax_t)p->md_virt, (uintmax_t)p->md_pages);
if (p->md_attr & EFI_MD_ATTR_UC)
printf("UC ");
if (p->md_attr & EFI_MD_ATTR_WC)
printf("WC ");
if (p->md_attr & EFI_MD_ATTR_WT)
printf("WT ");
if (p->md_attr & EFI_MD_ATTR_WB)
printf("WB ");
if (p->md_attr & EFI_MD_ATTR_UCE)
printf("UCE ");
if (p->md_attr & EFI_MD_ATTR_WP)
printf("WP ");
if (p->md_attr & EFI_MD_ATTR_RP)
printf("RP ");
if (p->md_attr & EFI_MD_ATTR_XP)
printf("XP ");
if (p->md_attr & EFI_MD_ATTR_NV)
printf("NV ");
if (p->md_attr & EFI_MD_ATTR_MORE_RELIABLE)
printf("MORE_RELIABLE ");
if (p->md_attr & EFI_MD_ATTR_RO)
printf("RO ");
if (p->md_attr & EFI_MD_ATTR_RT)
printf("RUNTIME");
printf("\n");
}
void
efi_map_print_entries(struct efi_map_header *efihdr)
{
printf("%23s %12s %12s %8s %4s\n",
"Type", "Physical", "Virtual", "#Pages", "Attr");
efi_map_foreach_entry(efihdr, print_efi_map_entry, NULL);
}