svn commit: r277412 - head/sys/powerpc/ofw
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Tue Jan 20 05:44:22 UTC 2015
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;
}
More information about the svn-src-all
mailing list