Index: sys/amd64/amd64/pmap.c =================================================================== --- sys/amd64/amd64/pmap.c +++ sys/amd64/amd64/pmap.c @@ -639,6 +639,13 @@ #define PMAP_ENTER_NORECLAIM 0x1000000 /* Don't reclaim PV entries. */ #define PMAP_ENTER_NOREPLACE 0x2000000 /* Don't replace mappings. */ +/* + * Internal flags for pmap_mapdev_internal() and + * pmap_change_attr_locked(). + */ +#define MAPDEV_FLUSHCACHE 0x0000001 /* Flush cache after mapping. */ +#define MAPDEV_SETATTR 0x0000002 /* Modify existing attrs. */ + static void free_pv_chunk(struct pv_chunk *pc); static void free_pv_entry(pmap_t pmap, pv_entry_t pv); static pv_entry_t get_pv_entry(pmap_t pmap, struct rwlock **lockp); @@ -659,7 +666,7 @@ vm_offset_t va); static int pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode, - bool noflush); + int flags); static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); static boolean_t pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va, struct rwlock **lockp); @@ -7181,7 +7188,7 @@ * NOT real memory. */ static void * -pmap_mapdev_internal(vm_paddr_t pa, vm_size_t size, int mode, bool noflush) +pmap_mapdev_internal(vm_paddr_t pa, vm_size_t size, int mode, int flags) { struct pmap_preinit_mapping *ppim; vm_offset_t va, offset; @@ -7215,7 +7222,7 @@ for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { ppim = pmap_preinit_mapping + i; if (ppim->pa == pa && ppim->sz == size && - ppim->mode == mode) + (ppim->mode == mode || !(flags & MAPDEV_SETATTR))) return ((void *)(ppim->va + offset)); } /* @@ -7224,9 +7231,12 @@ */ if (pa < dmaplimit && pa + size <= dmaplimit) { va = PHYS_TO_DMAP(pa); - PMAP_LOCK(kernel_pmap); - i = pmap_change_attr_locked(va, size, mode, noflush); - PMAP_UNLOCK(kernel_pmap); + if (flags & MAPDEV_SETATTR) { + PMAP_LOCK(kernel_pmap); + i = pmap_change_attr_locked(va, size, mode, flags); + PMAP_UNLOCK(kernel_pmap); + } else + i = 0; if (!i) return ((void *)(va + offset)); } @@ -7237,7 +7247,7 @@ for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); - if (!noflush) + if (flags & MAPDEV_FLUSHCACHE) pmap_invalidate_cache_range(va, va + tmpsize); return ((void *)(va + offset)); } @@ -7246,28 +7256,38 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) { - return (pmap_mapdev_internal(pa, size, mode, false)); + return (pmap_mapdev_internal(pa, size, mode, MAPDEV_FLUSHCACHE | + MAPDEV_SETATTR)); } void * pmap_mapdev(vm_paddr_t pa, vm_size_t size) { - return (pmap_mapdev_internal(pa, size, PAT_UNCACHEABLE, false)); + return (pmap_mapdev_attr(pa, size, PAT_UNCACHEABLE)); } void * pmap_mapdev_pciecfg(vm_paddr_t pa, vm_size_t size) { - return (pmap_mapdev_internal(pa, size, PAT_UNCACHEABLE, true)); + return (pmap_mapdev_internal(pa, size, PAT_UNCACHEABLE, + MAPDEV_SETATTR)); } void * pmap_mapbios(vm_paddr_t pa, vm_size_t size) { - return (pmap_mapdev_internal(pa, size, PAT_WRITE_BACK, false)); + return (pmap_mapdev_attr(pa, size, PAT_WRITE_BACK)); +} + +void * +pmap_mapphys(vm_paddr_t pa, vm_size_t size) +{ + + return (pmap_mapdev_internal(pa, size, PAT_WRITE_BACK, + MAPDEV_FLUSHCACHE)); } void @@ -7406,13 +7426,13 @@ int error; PMAP_LOCK(kernel_pmap); - error = pmap_change_attr_locked(va, size, mode, false); + error = pmap_change_attr_locked(va, size, mode, MAPDEV_FLUSHCACHE); PMAP_UNLOCK(kernel_pmap); return (error); } static int -pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode, bool noflush) +pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode, int flags) { vm_offset_t base, offset, tmpva; vm_paddr_t pa_start, pa_end, pa_end1; @@ -7529,7 +7549,7 @@ /* Run ended, update direct map. */ error = pmap_change_attr_locked( PHYS_TO_DMAP(pa_start), - pa_end - pa_start, mode, noflush); + pa_end - pa_start, mode, flags); if (error != 0) break; /* Start physical address run. */ @@ -7559,7 +7579,7 @@ /* Run ended, update direct map. */ error = pmap_change_attr_locked( PHYS_TO_DMAP(pa_start), - pa_end - pa_start, mode, noflush); + pa_end - pa_start, mode, flags); if (error != 0) break; /* Start physical address run. */ @@ -7587,7 +7607,7 @@ /* Run ended, update direct map. */ error = pmap_change_attr_locked( PHYS_TO_DMAP(pa_start), - pa_end - pa_start, mode, noflush); + pa_end - pa_start, mode, flags); if (error != 0) break; /* Start physical address run. */ @@ -7602,7 +7622,7 @@ pa_end1 = MIN(pa_end, dmaplimit); if (pa_start != pa_end1) error = pmap_change_attr_locked(PHYS_TO_DMAP(pa_start), - pa_end1 - pa_start, mode, noflush); + pa_end1 - pa_start, mode, flags); } /* @@ -7611,7 +7631,7 @@ */ if (changed) { pmap_invalidate_range(kernel_pmap, base, tmpva); - if (!noflush) + if (flags & MAPDEV_FLUSHCACHE) pmap_invalidate_cache_range(base, tmpva); } return (error); Index: sys/amd64/include/pmap.h =================================================================== --- sys/amd64/include/pmap.h +++ sys/amd64/include/pmap.h @@ -418,6 +418,7 @@ #define pmap_page_get_memattr(m) ((vm_memattr_t)(m)->md.pat_mode) #define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0) #define pmap_unmapbios(va, sz) pmap_unmapdev((va), (sz)) +#define pmap_unmapphys(va, sz) pmap_unmapdev((va), (sz)) struct thread; @@ -441,6 +442,7 @@ void *pmap_mapdev(vm_paddr_t, vm_size_t); void *pmap_mapdev_attr(vm_paddr_t, vm_size_t, int); void *pmap_mapdev_pciecfg(vm_paddr_t pa, vm_size_t size); +void *pmap_mapphys(vm_paddr_t, vm_size_t); boolean_t pmap_page_is_mapped(vm_page_t m); void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma); void pmap_pinit_pml4(vm_page_t); Index: sys/dev/acpica/Osd/OsdMemory.c =================================================================== --- sys/dev/acpica/Osd/OsdMemory.c +++ sys/dev/acpica/Osd/OsdMemory.c @@ -57,13 +57,13 @@ void * AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length) { - return (pmap_mapbios((vm_offset_t)PhysicalAddress, Length)); + return (pmap_mapphys((vm_offset_t)PhysicalAddress, Length)); } void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length) { - pmap_unmapbios((vm_offset_t)LogicalAddress, Length); + pmap_unmapphys((vm_offset_t)LogicalAddress, Length); } ACPI_STATUS