Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Apr 2015 13:21:28 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r281493 - head/sys/arm/arm
Message-ID:  <201504131321.t3DDLScR091302@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Mon Apr 13 13:21:27 2015
New Revision: 281493
URL: https://svnweb.freebsd.org/changeset/base/281493

Log:
  Update the arm devmap code to also work with arm64.
  
  There are a few differences between the two. On arm we need to provide a
  list of addresses we may be mapping before we have initialised the virtual
  memory subsystem, however on arm64 we allocate a small (2MiB for a 4k
  granule) range to be used for such purposes.
  
  Differential Revision:	https://reviews.freebsd.org/D2249
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/arm/arm/devmap.c

Modified: head/sys/arm/arm/devmap.c
==============================================================================
--- head/sys/arm/arm/devmap.c	Mon Apr 13 10:32:53 2015	(r281492)
+++ head/sys/arm/arm/devmap.c	Mon Apr 13 13:21:27 2015	(r281493)
@@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$");
 
 /*
  * Routines for mapping device memory.
+ *
+ * This is used on both arm and arm64.
  */
 
 #include "opt_ddb.h"
@@ -40,10 +42,18 @@ __FBSDID("$FreeBSD$");
 #include <vm/pmap.h>
 #include <machine/armreg.h>
 #include <machine/devmap.h>
+#include <machine/vmparam.h>
 
 static const struct arm_devmap_entry *devmap_table;
 static boolean_t devmap_bootstrap_done = false;
 
+#if defined(__aarch64__)
+#define	MAX_VADDR	VM_MAX_KERNEL_ADDRESS
+#define	PTE_DEVICE	VM_MEMATTR_DEVICE
+#elif defined(__arm__)
+#define	MAX_VADDR	ARM_VECTORS_HIGH
+#endif
+
 /*
  * The allocated-kva (akva) devmap table and metadata.  Platforms can call
  * arm_devmap_add_entry() to add static device mappings to this table using
@@ -53,7 +63,11 @@ static boolean_t devmap_bootstrap_done =
 #define	AKVA_DEVMAP_MAX_ENTRIES	32
 static struct arm_devmap_entry	akva_devmap_entries[AKVA_DEVMAP_MAX_ENTRIES];
 static u_int			akva_devmap_idx;
-static vm_offset_t		akva_devmap_vaddr = ARM_VECTORS_HIGH;
+static vm_offset_t		akva_devmap_vaddr = MAX_VADDR;
+
+#ifdef __aarch64__
+extern int early_boot;
+#endif
 
 /*
  * Print the contents of the static mapping table using the provided printf-like
@@ -99,7 +113,7 @@ arm_devmap_lastaddr()
 	if (akva_devmap_idx > 0)
 		return (akva_devmap_vaddr);
 
-	lowaddr = ARM_VECTORS_HIGH;
+	lowaddr = MAX_VADDR;
 	for (pd = devmap_table; pd != NULL && pd->pd_size != 0; ++pd) {
 		if (lowaddr > pd->pd_va)
 			lowaddr = pd->pd_va;
@@ -136,9 +150,12 @@ arm_devmap_add_entry(vm_paddr_t pa, vm_s
 	 * align the virtual address to the next-lower 1MB boundary so that we
 	 * end up with a nice efficient section mapping.
 	 */
+#ifdef __arm__
 	if ((pa & 0x000fffff) == 0 && (sz & 0x000fffff) == 0) {
 		akva_devmap_vaddr = trunc_1mpage(akva_devmap_vaddr - sz);
-	} else {
+	} else
+#endif
+	{
 		akva_devmap_vaddr = trunc_page(akva_devmap_vaddr - sz);
 	}
 	m = &akva_devmap_entries[akva_devmap_idx++];
@@ -186,8 +203,12 @@ arm_devmap_bootstrap(vm_offset_t l1pt, c
 		return;
 
 	for (pd = devmap_table; pd->pd_size != 0; ++pd) {
+#if defined(__arm__)
 		pmap_map_chunk(l1pt, pd->pd_va, pd->pd_pa, pd->pd_size,
 		    pd->pd_prot,pd->pd_cache);
+#elif defined(__aarch64__)
+		pmap_kenter_device(pd->pd_va, pd->pd_size, pd->pd_pa);
+#endif
 	}
 }
 
@@ -252,17 +273,25 @@ pmap_mapdev(vm_offset_t pa, vm_size_t si
 	/* First look in the static mapping table. */
 	if ((rva = arm_devmap_ptov(pa, size)) != NULL)
 		return (rva);
-	
+
 	offset = pa & PAGE_MASK;
 	pa = trunc_page(pa);
 	size = round_page(size + offset);
-	
-	va = kva_alloc(size);
+
+#ifdef __aarch64__
+	if (early_boot) {
+		akva_devmap_vaddr = trunc_page(akva_devmap_vaddr - size);
+		va = akva_devmap_vaddr;
+		KASSERT(va >= VM_MAX_KERNEL_ADDRESS - L2_SIZE,
+		    ("Too many early devmap mappings"));
+	} else
+#endif
+		va = kva_alloc(size);
 	if (!va)
 		panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 
 	pmap_kenter_device(va, size, pa);
-	
+
 	return ((void *)(va + offset));
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504131321.t3DDLScR091302>