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));
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to