diff --git a/sys/amd64/amd64/efirt_machdep.c b/sys/amd64/amd64/efirt_machdep.c --- a/sys/amd64/amd64/efirt_machdep.c +++ b/sys/amd64/amd64/efirt_machdep.c @@ -180,6 +180,25 @@ return (pte); } +static int +efi_convattr(uint32_t attr) +{ + int mode = -1; + + if ((attr & EFI_MD_ATTR_WB) != 0) + mode = VM_MEMATTR_WRITE_BACK; + else if ((attr & EFI_MD_ATTR_WT) != 0) + mode = VM_MEMATTR_WRITE_THROUGH; + else if ((attr & EFI_MD_ATTR_WC) != 0) + mode = VM_MEMATTR_WRITE_COMBINING; + else if ((attr & EFI_MD_ATTR_WP) != 0) + mode = VM_MEMATTR_WRITE_PROTECTED; + else if ((attr & EFI_MD_ATTR_UC) != 0) + mode = VM_MEMATTR_UNCACHEABLE; + + return (mode); +} + bool efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) { @@ -190,6 +209,7 @@ vm_offset_t va; uint64_t idx; int bits, i, mode; + bool map_pz; obj_1t1_pt = vm_pager_allocate(OBJT_PHYS, NULL, ptoa(1 + NPML4EPG + NPML4EPG * NPDPEPG + NPML4EPG * NPDPEPG * NPDEPG), @@ -238,17 +258,8 @@ (uintmax_t)p->md_pages); goto fail; } - if ((p->md_attr & EFI_MD_ATTR_WB) != 0) - mode = VM_MEMATTR_WRITE_BACK; - else if ((p->md_attr & EFI_MD_ATTR_WT) != 0) - mode = VM_MEMATTR_WRITE_THROUGH; - else if ((p->md_attr & EFI_MD_ATTR_WC) != 0) - mode = VM_MEMATTR_WRITE_COMBINING; - else if ((p->md_attr & EFI_MD_ATTR_WP) != 0) - mode = VM_MEMATTR_WRITE_PROTECTED; - else if ((p->md_attr & EFI_MD_ATTR_UC) != 0) - mode = VM_MEMATTR_UNCACHEABLE; - else { + mode = efi_convattr(p->md_attr); + if (mode == -1) { if (bootverbose) printf("EFI Runtime entry %d mapping " "attributes unsupported\n", i); @@ -274,6 +285,23 @@ VM_OBJECT_WUNLOCK(obj_1t1_pt); } + TUNABLE_BOOL_FETCH("machdep.efirt.map_pz", &map_pz); + if (map_pz) { + VM_OBJECT_WLOCK(obj_1t1_pt); + pte = efi_1t1_pte(0); + /* XXX Assume first entry points to PA 0? */ + mode = efi_convattr(map->md_attr); + if (mode == -1) { + printf("EFI Runtime page 0 mapping attributes " + "unsupported\n"); + mode = VM_MEMATTR_UNCACHEABLE; + } + bits = pmap_cache_bits(kernel_pmap, mode, false) | X86_PG_RW | + X86_PG_V; + pte_store(pte, bits); + VM_OBJECT_WUNLOCK(obj_1t1_pt); + } + return (true); fail: