Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 May 2014 15:57:12 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r265272 - projects/arm64/sys/arm64/arm64
Message-ID:  <201405031557.s43FvC2V031613@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Sat May  3 15:57:12 2014
New Revision: 265272
URL: http://svnweb.freebsd.org/changeset/base/265272

Log:
  Flesh out the early pmap code more, start to allocate early address space.

Modified:
  projects/arm64/sys/arm64/arm64/pmap.c

Modified: projects/arm64/sys/arm64/arm64/pmap.c
==============================================================================
--- projects/arm64/sys/arm64/arm64/pmap.c	Sat May  3 15:53:13 2014	(r265271)
+++ projects/arm64/sys/arm64/arm64/pmap.c	Sat May  3 15:57:12 2014	(r265272)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_page.h>
 #include <vm/vm_map.h>
 
+#include <machine/machdep.h>
 #include <machine/vmparam.h>
 
 #if !defined(DIAGNOSTIC)
@@ -58,14 +59,45 @@ struct pmap kernel_pmap_store;
 
 struct msgbuf *msgbufp = NULL;
 
+static pt_entry_t *
+pmap_early_page_idx(vm_offset_t l1pt, vm_offset_t va, uint64_t kern_delta,
+    u_int *l1_slot, u_int *l2_slot)
+{
+	pt_entry_t *ptep;
+	pd_entry_t *pde;
+
+	pde = (pd_entry_t *)l1pt;
+	*l1_slot = (KERNBASE >> L1_SHIFT) & Ln_ADDR_MASK;
+
+	/* Check locore has used a table L1 map */
+	KASSERT((pde[*l1_slot] & ATTR_DESCR_MASK) == L1_TABLE,
+	   ("Invalid bootstrap L1 table"));
+	/* Find the address of the L2 table */
+	ptep = (pt_entry_t *)((pde[*l1_slot] & ~ATTR_MASK) + kern_delta);
+	*l2_slot = (KERNBASE >> L2_SHIFT) & Ln_ADDR_MASK;
+
+	return (ptep);
+}
+
+static vm_paddr_t
+pmap_early_vtophys(vm_offset_t l1pt, vm_offset_t va, uint64_t kern_delta)
+{
+	u_int l1_slot, l2_slot;
+	pt_entry_t *ptep;
+
+	ptep = pmap_early_page_idx(l1pt, va, kern_delta, &l1_slot, &l2_slot);
+
+	return (ptep[l2_slot] & ~ATTR_MASK);
+}
+
 void
 pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen)
 {
-	u_int l1_slot, l2_slot;
+	u_int l1_slot, l2_slot, avail_slot, map_slot;
 	uint64_t kern_delta;
 	pt_entry_t *ptep;
-	pd_entry_t *pde;
-	vm_offset_t va;
+	vm_offset_t va, freemempos;
+	vm_offset_t dpcpu;
 	vm_paddr_t pa;
 
 	kern_delta = KERNBASE - kernstart;
@@ -74,36 +106,46 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd
 	printf("%llx\n", l1pt);
 	printf("%lx\n", (KERNBASE >> L1_SHIFT) & Ln_ADDR_MASK);
 
+	va = KERNBASE;
+	pa = KERNBASE - kern_delta;
+
+	/*
+	 * Start to initialise phys_avail by copying from physmap
+	 * up to the physicaladdress KERNBASE points at.
+	 */
+	for (avail_slot = 0; avail_slot < physmap_idx; avail_slot += 2) {
+		if (physmap[avail_slot] <= pa &&
+		    physmap[avail_slot] + physmap[avail_slot + 1] > pa)
+			break;
+
+		phys_avail[avail_slot] = physmap[avail_slot];
+		phys_avail[avail_slot + 1] = physmap[avail_slot + 1];
+	}
+
+	/* Add the memory before the kernel */
+	if (physmap[avail_slot] != pa) {
+		phys_avail[avail_slot] = physmap[avail_slot];
+		phys_avail[avail_slot + 1] = pa - physmap[avail_slot];
+		avail_slot += 2;
+	}
+	map_slot = avail_slot;
+
 	/*
 	 * Read the page table to find out what is already mapped.
 	 * This assumes we have mapped a block of memory from KERNBASE
 	 * using a single L1 entry.
 	 */
-	pde = (pd_entry_t *)l1pt;
-	l1_slot = (KERNBASE >> L1_SHIFT) & Ln_ADDR_MASK;
-
-	/* Sanity check the index, KERNBASE should be the first VA */
-	KASSERT(l1_slot == 0, ("The L1 index is non-zero"));
-	/* Check locore has used a table L1 map */
-	KASSERT((pde[l1_slot] & ATTR_DESCR_MASK) == L1_TABLE,
-	   ("Invalid bootstrap L1 table"));
+	ptep = pmap_early_page_idx(l1pt, KERNBASE, kern_delta, &l1_slot,
+	    &l2_slot);
 
-	/* Find the address of the L2 table */
-	ptep = (pt_entry_t *)((pde[l1_slot] & ~ATTR_MASK) + kern_delta);
-	l2_slot = (KERNBASE >> L2_SHIFT) & Ln_ADDR_MASK;
 	/* Sanity check the index, KERNBASE should be the first VA */
 	KASSERT(l2_slot == 0, ("The L2 index is non-zero"));
 
-	va = KERNBASE;
-	pa = KERNBASE - kern_delta; /* Set to an invalid address */
-
 	/* Find how many pages we have mapped */
 	for (; l2_slot < Ln_ENTRIES; l2_slot++) {
 		if ((ptep[l2_slot] & ATTR_DESCR_MASK) == 0)
 			break;
 
-		printf("ptep[%u] = %016llx\n", l2_slot, ptep[l2_slot]);
-
 		/* Check locore used L2 blocks */
 		KASSERT((ptep[l2_slot] & ATTR_DESCR_MASK) == L2_BLOCK,
 		    ("Invalid bootstrap L2 table"));
@@ -113,12 +155,19 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd
 		va += L2_SIZE;
 		pa += L2_SIZE;
 	}
+
 	/* And map the rest of L2 table */
 	for (; l2_slot < Ln_ENTRIES; l2_slot++) {
 		KASSERT(ptep[l2_slot] == 0, ("Invalid bootstrap L2 table"));
 		KASSERT(((va >> L2_SHIFT) & Ln_ADDR_MASK) == l2_slot,
 		    ("VA inconsistency detected"));
 
+		if (pa >= physmap[map_slot] + physmap[map_slot + 1]) {
+			map_slot += 2;
+			KASSERT(map_slot < physmap_idx, ("..."));
+			pa = physmap[map_slot];
+		}
+
 		/* TODO: Check if this pa is valid */
 		ptep[l2_slot] = (pa & ~L2_OFFSET) | ATTR_AF | L2_BLOCK;
 
@@ -134,6 +183,18 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd
 	    "tlbi vmalle1is	\n"
 	    "dsb  sy		\n"
 	    "isb		\n");
+
+	freemempos = KERNBASE + kernlen;
+	freemempos = roundup2(freemempos, PAGE_SIZE);
+
+#define alloc_pages(var, np)						\
+	(var) = freemempos;						\
+	freemempos += (np * PAGE_SIZE);					\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	/* Allocate dynamic per-cpu area. */
+	alloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu, 0);
 }
 
 /*



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