Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Jan 2015 05:44:21 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r277412 - head/sys/powerpc/ofw
Message-ID:  <201501200544.t0K5iLdf095579@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Tue Jan 20 05:44:21 2015
New Revision: 277412
URL: https://svnweb.freebsd.org/changeset/base/277412

Log:
  Remove space in the FDT reservation map from the available memory regions
  in ofw_mem_regions(). This function is actually MI and should move to
  dev/ofw at some point in the near future so that ARM and MIPS can use the
  same code.

Modified:
  head/sys/powerpc/ofw/ofw_machdep.c

Modified: head/sys/powerpc/ofw/ofw_machdep.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c	Tue Jan 20 05:28:03 2015	(r277411)
+++ head/sys/powerpc/ofw/ofw_machdep.c	Tue Jan 20 05:44:21 2015	(r277412)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/smp.h>
 #include <sys/stat.h>
+#include <sys/endian.h>
 
 #include <net/ethernet.h>
 
@@ -211,12 +212,89 @@ parse_ofw_memory(phandle_t node, const c
 	return (sz);
 }
 
+static int
+excise_fdt_reserved(struct mem_region *avail, int asz)
+{
+	struct {
+		uint64_t address;
+		uint64_t size;
+	} fdtmap[16];
+	ssize_t fdtmapsize;
+	phandle_t chosen;
+	int i, j, k;
+
+	chosen = OF_finddevice("/chosen");
+	fdtmapsize = OF_getprop(chosen, "fdtmemreserv", fdtmap, sizeof(fdtmap));
+
+	for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
+		fdtmap[j].address = be64toh(fdtmap[j].address);
+		fdtmap[j].size = be64toh(fdtmap[j].size);
+	}
+
+	for (i = 0; i < asz; i++) {
+		for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
+			/*
+			 * Case 1: Exclusion region encloses complete
+			 * available entry. Drop it and move on.
+			 */
+			if (fdtmap[j].address <= avail[i].mr_start &&
+			    fdtmap[j].address + fdtmap[j].size >=
+			    avail[i].mr_start + avail[i].mr_size) {
+				for (k = i+1; k < asz; k++)
+					avail[k-1] = avail[k];
+				asz--;
+				i--; /* Repeat some entries */
+				continue;
+			}
+
+			/*
+			 * Case 2: Exclusion region starts in available entry.
+			 * Trim it to where the entry begins and append
+			 * a new available entry with the region after
+			 * the excluded region, if any.
+			 */
+			if (fdtmap[j].address >= avail[i].mr_start &&
+			    fdtmap[j].address < avail[i].mr_start +
+			    avail[i].mr_size) {
+				if (fdtmap[j].address + fdtmap[j].size < 
+				    avail[i].mr_start + avail[i].mr_size) {
+					avail[asz].mr_start =
+					    roundup2(fdtmap[j].address +
+					    fdtmap[j].size, PAGE_SIZE);
+					avail[asz].mr_size = avail[i].mr_start +
+					     avail[i].mr_size -
+					     avail[asz].mr_start;
+					asz++;
+				}
+
+				avail[i].mr_size =
+				    rounddown2(fdtmap[j].address, PAGE_MASK) -
+				    avail[i].mr_start;
+			}
+
+			/*
+			 * Case 3: Exclusion region ends in available entry.
+			 * Move start point to where the exclusion zone ends.
+			 * The case of a contained exclusion zone has already
+			 * been caught in case 2.
+			 */
+			if (fdtmap[j].address + fdtmap[j].size >=
+			    avail[i].mr_start && fdtmap[j].address +
+			    fdtmap[j].size < avail[i].mr_start +
+			    avail[i].mr_size) {
+				avail[i].mr_start =
+				    roundup2(fdtmap[j].address + fdtmap[j].size,				    PAGE_MASK);
+			}
+		}
+	}
+
+	return (asz);
+}
+
 /*
  * This is called during powerpc_init, before the system is really initialized.
  * It shall provide the total and the available regions of RAM.
- * Both lists must have a zero-size entry as terminator.
- * The available regions need not take the kernel into account, but needs
- * to provide space for two additional entry beyond the terminating one.
+ * The available regions need not take the kernel into account.
  */
 void
 ofw_mem_regions(struct mem_region *memp, int *memsz,
@@ -236,7 +314,8 @@ ofw_mem_regions(struct mem_region *memp,
 	    phandle = OF_peer(phandle)) {
 		if (OF_getprop(phandle, "name", name, sizeof(name)) <= 0)
 			continue;
-		if (strncmp(name, "memory", sizeof(name)) != 0)
+		if (strncmp(name, "memory", sizeof(name)) != 0 &&
+		    strncmp(name, "memory@", strlen("memory@")) != 0)
 			continue;
 
 		res = parse_ofw_memory(phandle, "reg", &memp[msz]);
@@ -249,6 +328,10 @@ ofw_mem_regions(struct mem_region *memp,
 		asz += res/sizeof(struct mem_region);
 	}
 
+	phandle = OF_finddevice("/chosen");
+	if (OF_hasprop(phandle, "fdtmemreserv"))
+		asz = excise_fdt_reserved(availp, asz);
+
 	*memsz = msz;
 	*availsz = asz;
 }



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