summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm64/arm64/machdep.c156
-rw-r--r--sys/arch/arm64/arm64/pmap.c10
-rw-r--r--sys/arch/arm64/dev/efi.c11
-rw-r--r--sys/arch/arm64/include/pmap.h6
4 files changed, 112 insertions, 71 deletions
diff --git a/sys/arch/arm64/arm64/machdep.c b/sys/arch/arm64/arm64/machdep.c
index d3ad1effb6d..702f12e6929 100644
--- a/sys/arch/arm64/arm64/machdep.c
+++ b/sys/arch/arm64/arm64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.25 2018/01/10 23:27:18 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.26 2018/01/12 14:52:55 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
*
@@ -746,6 +746,8 @@ uint32_t mmap_desc_ver;
EFI_MEMORY_DESCRIPTOR *mmap;
+void remap_efi_runtime(EFI_PHYSICAL_ADDRESS);
+
void collect_kernel_args(char *);
void process_kernel_args(void);
@@ -821,9 +823,6 @@ initarm(struct arm64_bootparams *abp)
process_kernel_args();
- // XXX
- paddr_t pmap_steal_avail(size_t size, int align, void **kva);
-
void _start(void);
long kernbase = (long)&_start & ~0x00fff;
@@ -922,67 +921,8 @@ initarm(struct arm64_bootparams *abp)
arm64_a4x_bs_tag._space_map = map_a4x_func_save;
/* Remap EFI runtime. */
- if (mmap_start != 0 && system_table != 0) {
- EFI_SYSTEM_TABLE *st = (EFI_SYSTEM_TABLE *)system_table;
- EFI_RUNTIME_SERVICES *rs;
- EFI_STATUS status;
- EFI_MEMORY_DESCRIPTOR *src;
- EFI_MEMORY_DESCRIPTOR *dst;
- EFI_PHYSICAL_ADDRESS phys_start = ~0ULL;
- EFI_VIRTUAL_ADDRESS virt_start;
- vsize_t space;
- int i, count = 0;
- paddr_t pa;
-
- /*
- * Pick a random address somewhere in the lower half
- * of the usable virtual address space.
- */
- space = 3 * (VM_MAX_ADDRESS - VM_MIN_ADDRESS) / 4;
- virt_start = VM_MIN_ADDRESS +
- ((vsize_t)arc4random_uniform(space >> PAGE_SHIFT) << PAGE_SHIFT);
-
- /* Make sure the EFI system table is mapped. */
- pmap_map_early(system_table, sizeof(EFI_SYSTEM_TABLE));
- rs = st->RuntimeServices;
-
- /* Make sure memory for EFI runtime services is mapped. */
- src = mmap;
- for (i = 0; i < mmap_size / mmap_desc_size; i++) {
- if (src->Attribute & EFI_MEMORY_RUNTIME) {
- pmap_map_early(src->PhysicalStart,
- src->NumberOfPages * PAGE_SIZE);
- if (phys_start > src->PhysicalStart)
- phys_start = src->PhysicalStart;
- count++;
- }
- src = NextMemoryDescriptor(src, mmap_desc_size);
- }
-
- /* Allocate memory descriptors for new mappings. */
- pa = pmap_steal_avail(count * mmap_desc_size,
- mmap_desc_size, NULL);
- memset((void *)pa, 0, count * mmap_desc_size);
-
- src = mmap;
- dst = (EFI_MEMORY_DESCRIPTOR *)pa;
- for (i = 0; i < mmap_size / mmap_desc_size; i++) {
- if (src->Attribute & EFI_MEMORY_RUNTIME) {
- src->VirtualStart = virt_start +
- (src->PhysicalStart - phys_start);
- memcpy(dst, src, mmap_desc_size);
- dst = NextMemoryDescriptor(dst, mmap_desc_size);
- }
- src = NextMemoryDescriptor(src, mmap_desc_size);
- }
-
- /* Install new mappings. */
- dst = (EFI_MEMORY_DESCRIPTOR *)pa;
- status = rs->SetVirtualAddressMap(count * mmap_desc_size,
- mmap_desc_size, mmap_desc_ver, dst);
- if (status != EFI_SUCCESS)
- printf("SetVirtualAddressMap failed: %lu\n", status);
- }
+ if (mmap_start != 0 && system_table != 0)
+ remap_efi_runtime(system_table);
/* XXX */
pmap_avail_fixup();
@@ -1077,6 +1017,92 @@ initarm(struct arm64_bootparams *abp)
splraise(IPL_IPI);
}
+void
+remap_efi_runtime(EFI_PHYSICAL_ADDRESS system_table)
+{
+ EFI_SYSTEM_TABLE *st = (EFI_SYSTEM_TABLE *)system_table;
+ EFI_RUNTIME_SERVICES *rs;
+ EFI_STATUS status;
+ EFI_MEMORY_DESCRIPTOR *src;
+ EFI_MEMORY_DESCRIPTOR *dst;
+ EFI_PHYSICAL_ADDRESS phys_start = ~0ULL;
+ EFI_PHYSICAL_ADDRESS phys_end = 0;
+ EFI_VIRTUAL_ADDRESS virt_start;
+ vsize_t space;
+ int i, count = 0;
+ paddr_t pa;
+
+ /*
+ * Pick a random address somewhere in the lower half of the
+ * usable virtual address space.
+ */
+ space = 3 * (VM_MAX_ADDRESS - VM_MIN_ADDRESS) / 4;
+ virt_start = VM_MIN_ADDRESS +
+ ((vsize_t)arc4random_uniform(space >> PAGE_SHIFT) << PAGE_SHIFT);
+
+ /* Make sure the EFI system table is mapped. */
+ pmap_map_early(system_table, sizeof(EFI_SYSTEM_TABLE));
+ rs = st->RuntimeServices;
+
+ /*
+ * Make sure memory for EFI runtime services is mapped. We
+ * only map normal memory at this point and pray that the
+ * SetVirtualAddressMap call doesn't need anything else.
+ */
+ src = mmap;
+ for (i = 0; i < mmap_size / mmap_desc_size; i++) {
+ if (src->Attribute & EFI_MEMORY_RUNTIME) {
+ if (src->Attribute & EFI_MEMORY_WB) {
+ pmap_map_early(src->PhysicalStart,
+ src->NumberOfPages * PAGE_SIZE);
+ phys_start = MIN(phys_start,
+ src->PhysicalStart);
+ phys_end = MAX(phys_end, src->PhysicalStart +
+ src->NumberOfPages * PAGE_SIZE);
+ }
+ count++;
+ }
+ src = NextMemoryDescriptor(src, mmap_desc_size);
+ }
+
+ /* Allocate memory descriptors for new mappings. */
+ pa = pmap_steal_avail(count * mmap_desc_size,
+ mmap_desc_size, NULL);
+ memset((void *)pa, 0, count * mmap_desc_size);
+
+ /*
+ * Establish new mappings. Apparently some EFI code relies on
+ * the offset between code and data remaining the same so pick
+ * virtual addresses for normal memory that meet that
+ * constraint. Other mappings are simply tagged to the end of
+ * the last normal memory mapping.
+ */
+ src = mmap;
+ dst = (EFI_MEMORY_DESCRIPTOR *)pa;
+ for (i = 0; i < mmap_size / mmap_desc_size; i++) {
+ if (src->Attribute & EFI_MEMORY_RUNTIME) {
+ if (src->Attribute & EFI_MEMORY_WB) {
+ src->VirtualStart = virt_start +
+ (src->PhysicalStart - phys_start);
+ } else {
+ src->VirtualStart = virt_start +
+ (phys_end - phys_start);
+ phys_end += src->NumberOfPages * PAGE_SIZE;
+ }
+ memcpy(dst, src, mmap_desc_size);
+ dst = NextMemoryDescriptor(dst, mmap_desc_size);
+ }
+ src = NextMemoryDescriptor(src, mmap_desc_size);
+ }
+
+ /* Install new mappings. */
+ dst = (EFI_MEMORY_DESCRIPTOR *)pa;
+ status = rs->SetVirtualAddressMap(count * mmap_desc_size,
+ mmap_desc_size, mmap_desc_ver, dst);
+ if (status != EFI_SUCCESS)
+ printf("SetVirtualAddressMap failed: %lu\n", status);
+}
+
int comcnspeed = B115200;
char bootargs[MAX_BOOT_STRING];
diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c
index 22319d35aae..cfa70ba46ec 100644
--- a/sys/arch/arm64/arm64/pmap.c
+++ b/sys/arch/arm64/arm64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.43 2018/01/10 23:27:18 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.44 2018/01/12 14:52:55 kettenis Exp $ */
/*
* Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
*
@@ -454,10 +454,14 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
{
struct pte_desc *pted;
struct vm_page *pg;
- int s, cache, error;
+ int s, error;
+ int cache = PMAP_CACHE_WB;
int need_sync = 0;
- cache = (pa & PMAP_NOCACHE) ? PMAP_CACHE_CI : PMAP_CACHE_WB;
+ if (pa & PMAP_NOCACHE)
+ cache = PMAP_CACHE_CI;
+ if (pa & PMAP_DEVICE)
+ cache = PMAP_CACHE_DEV;
pg = PHYS_TO_VM_PAGE(pa);
/* MP - Acquire lock for this pmap */
diff --git a/sys/arch/arm64/dev/efi.c b/sys/arch/arm64/dev/efi.c
index ea1aaf35775..9a84863046f 100644
--- a/sys/arch/arm64/dev/efi.c
+++ b/sys/arch/arm64/dev/efi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efi.c,v 1.2 2018/01/10 23:27:18 kettenis Exp $ */
+/* $OpenBSD: efi.c,v 1.3 2018/01/12 14:52:55 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
@@ -134,10 +134,19 @@ efi_attach(struct device *parent, struct device *self, void *aux)
desc->Attribute);
#endif
+ /*
+ * Normal memory is expected to be "write
+ * back" cachable. Everything else is mapped
+ * as device memory.
+ */
+ if ((desc->Attribute & EFI_MEMORY_WB) == 0)
+ pa |= PMAP_DEVICE;
+
if (desc->Type == EfiRuntimeServicesCode)
prot |= PROT_EXEC;
else
prot |= PROT_WRITE;
+
while (npages--) {
pmap_enter(sc->sc_pm, va, pa, prot,
prot | PMAP_WIRED);
diff --git a/sys/arch/arm64/include/pmap.h b/sys/arch/arm64/include/pmap.h
index 0c16ae9eaaf..62dc6bfd246 100644
--- a/sys/arch/arm64/include/pmap.h
+++ b/sys/arch/arm64/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.8 2018/01/04 14:30:08 kettenis Exp $ */
+/* $OpenBSD: pmap.h,v 1.9 2018/01/12 14:52:55 kettenis Exp $ */
/*
* Copyright (c) 2008,2009,2014 Dale Rahn <drahn@dalerahn.com>
*
@@ -19,8 +19,9 @@
#include <arm64/pte.h>
-#define PMAP_PA_MASK ~((paddr_t)PAGE_MASK) /* to remove the flags */
+#define PMAP_PA_MASK ~((paddr_t)PAGE_MASK) /* to remove the flags */
#define PMAP_NOCACHE 0x1 /* non-cacheable memory */
+#define PMAP_DEVICE 0x2 /* device memory */
typedef struct pmap *pmap_t;
@@ -87,6 +88,7 @@ vaddr_t pmap_bootstrap(long kvo, paddr_t lpt1, long kernelstart,
long kernelend, long ram_start, long ram_end);
void pmap_page_ro(pmap_t pm, vaddr_t va, vm_prot_t prot);
+paddr_t pmap_steal_avail(size_t size, int align, void **kva);
void pmap_avail_fixup();
void pmap_physload_avail();