Index: sys/arm64/arm64/pmap.c =================================================================== --- sys/arm64/arm64/pmap.c +++ sys/arm64/arm64/pmap.c @@ -110,10 +110,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -145,6 +147,8 @@ #include #include +#include +#include #include #include #include @@ -5445,6 +5449,57 @@ return ((void *)(va + offset)); } +void *pmap_mapacpi(vm_paddr_t pa, vm_size_t size); /* TODO: header */ +void *pmap_mapacpi(vm_paddr_t pa, vm_size_t size) +{ + vm_offset_t va, offset; + pd_entry_t *pde; + int i, lvl, ndesc, mode = VM_MEMATTR_DEVICE; + size_t efisz; + struct efi_map_header *efihdr; + struct efi_md *map, *p; + caddr_t kmdp; + + /* Find mode using EFI (TODO: don't search preload etc. on every call) */ + kmdp = preload_search_by_type("elf kernel"); + efihdr = (struct efi_map_header *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_EFI_MAP); + efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; + map = (struct efi_md *)((uint8_t *)efihdr + efisz); + ndesc = efihdr->memory_size / efihdr->descriptor_size; + for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p, + efihdr->descriptor_size)) { + if (pa < p->md_phys || pa >= p->md_phys + p->md_pages * EFI_PAGE_SIZE) + continue; + if (p->md_type == EFI_MD_TYPE_IOMEM || p->md_type == EFI_MD_TYPE_IOPORT) + mode = VM_MEMATTR_DEVICE; + else if ((p->md_attr & EFI_MD_ATTR_WB) != 0 || p->md_type == EFI_MD_TYPE_RECLAIM) + 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; + break; + } + + offset = pa & PAGE_MASK; + size = round_page(offset + size); + + va = kva_alloc(size); + if (va == 0) + panic("%s: Couldn't allocate KVA", __func__); + + pde = pmap_pde(kernel_pmap, va, &lvl); + KASSERT(lvl == 2, ("pmap_mapbios: Invalid level %d", lvl)); + + /* L3 table is linked */ + va = trunc_page(va); + pa = trunc_page(pa); + pmap_kenter(va, size, pa, mode); + + return ((void *)(va + offset)); +} + void pmap_unmapbios(vm_offset_t va, vm_size_t size) { Index: sys/dev/acpica/Osd/OsdMemory.c =================================================================== --- sys/dev/acpica/Osd/OsdMemory.c +++ sys/dev/acpica/Osd/OsdMemory.c @@ -57,7 +57,8 @@ void * AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length) { - return (pmap_mapbios((vm_offset_t)PhysicalAddress, Length)); + extern void *pmap_mapacpi(vm_paddr_t pa, vm_size_t size); /* TODO: header */ + return (pmap_mapacpi((vm_offset_t)PhysicalAddress, Length)); } void