aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2020-06-28 15:03:07 +0000
committerAndrew Turner <andrew@FreeBSD.org>2020-06-28 15:03:07 +0000
commit23e42a83c15ff793f09906ddfa40574155fbcc5d (patch)
tree66553ebf2ae7ef44eaedccc27b461f8b2810b5f9 /sys
parente99ce3eac57bb1b0aafba87a961a2a6ba77d6846 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/arm64/arm64/machdep.c44
-rw-r--r--sys/arm64/arm64/pmap.c2
-rw-r--r--sys/arm64/include/machdep.h1
3 files changed, 45 insertions, 2 deletions
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index f5950eae1aab..fa698c7dbdaa 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -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
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 43a16d185ed9..709d7d17c0c8 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -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));
diff --git a/sys/arm64/include/machdep.h b/sys/arm64/include/machdep.h
index 4a39020d8f73..f3bd5d6c4838 100644
--- a/sys/arm64/include/machdep.h
+++ b/sys/arm64/include/machdep.h
@@ -56,6 +56,7 @@ vm_offset_t parse_boot_param(struct arm64_bootparams *abp);
#ifdef FDT
void parse_fdt_bootargs(void);
#endif
+int memory_mapping_mode(vm_paddr_t pa);
extern void (*pagezero)(void *);
#endif /* _KERNEL */