Author: andrew
Date: Sun Jun 28 15:03:07 2020
New Revision: 362726
URL: https://svnweb.freebsd.org/changeset/base/362726

Log:
  Use EFI memory map to determine attributes for Acpi mappings on arm64.
  
  AcpiOsMapMemory is used for device memory when e.g. an _INI method wants
  to access physical memory, however, aarch64 pmap_mapbios is hardcoded to
  writeback. Search for the correct memory type to use in pmap_mapbios.
  
  Submitted by: Greg V <greg_unrelenting.technology>
  Differential Revision:        https://reviews.freebsd.org/D25201

Modified:
  head/sys/arm64/arm64/machdep.c
  head/sys/arm64/arm64/pmap.c
  head/sys/arm64/include/machdep.h

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c      Sun Jun 28 14:40:48 2020        
(r362725)
+++ head/sys/arm64/arm64/machdep.c      Sun Jun 28 15:03:07 2020        
(r362726)
@@ -120,6 +120,7 @@ int has_pan;
  * passed into the kernel and used by the EFI code to call runtime services.
  */
 vm_paddr_t efi_systbl_phys;
+static struct efi_map_header *efihdr;
 
 /* pagezero_* implementations are provided in support.S */
 void pagezero_simple(void *);
@@ -1071,11 +1072,52 @@ cache_setup(void)
        }
 }
 
+int
+memory_mapping_mode(vm_paddr_t pa)
+{
+       struct efi_md *map, *p;
+       size_t efisz;
+       int ndesc, i;
+
+       if (efihdr == NULL)
+               return (VM_MEMATTR_WRITE_BACK);
+
+       /*
+        * Memory map data provided by UEFI via the GetMemoryMap
+        * Boot Services API.
+        */
+       efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+       map = (struct efi_md *)((uint8_t *)efihdr + efisz);
+
+       if (efihdr->descriptor_size == 0)
+               return (VM_MEMATTR_WRITE_BACK);
+       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)
+                       return (VM_MEMATTR_DEVICE);
+               else if ((p->md_attr & EFI_MD_ATTR_WB) != 0 ||
+                   p->md_type == EFI_MD_TYPE_RECLAIM)
+                       return (VM_MEMATTR_WRITE_BACK);
+               else if ((p->md_attr & EFI_MD_ATTR_WT) != 0)
+                       return (VM_MEMATTR_WRITE_THROUGH);
+               else if ((p->md_attr & EFI_MD_ATTR_WC) != 0)
+                       return (VM_MEMATTR_WRITE_COMBINING);
+               break;
+       }
+
+       return (VM_MEMATTR_DEVICE);
+}
+
 void
 initarm(struct arm64_bootparams *abp)
 {
        struct efi_fb *efifb;
-       struct efi_map_header *efihdr;
        struct pcpu *pcpup;
        char *env;
 #ifdef FDT

Modified: head/sys/arm64/arm64/pmap.c
==============================================================================
--- head/sys/arm64/arm64/pmap.c Sun Jun 28 14:40:48 2020        (r362725)
+++ head/sys/arm64/arm64/pmap.c Sun Jun 28 15:03:07 2020        (r362726)
@@ -5449,7 +5449,7 @@ pmap_mapbios(vm_paddr_t pa, vm_size_t size)
                /* L3 table is linked */
                va = trunc_page(va);
                pa = trunc_page(pa);
-               pmap_kenter(va, size, pa, VM_MEMATTR_WRITE_BACK);
+               pmap_kenter(va, size, pa, memory_mapping_mode(pa));
        }
 
        return ((void *)(va + offset));

Modified: head/sys/arm64/include/machdep.h
==============================================================================
--- head/sys/arm64/include/machdep.h    Sun Jun 28 14:40:48 2020        
(r362725)
+++ head/sys/arm64/include/machdep.h    Sun Jun 28 15:03:07 2020        
(r362726)
@@ -56,6 +56,7 @@ vm_offset_t parse_boot_param(struct arm64_bootparams *
 #ifdef FDT
 void parse_fdt_bootargs(void);
 #endif
+int memory_mapping_mode(vm_paddr_t pa);
 extern void (*pagezero)(void *);
 
 #endif /* _KERNEL */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to