From owner-svn-src-all@FreeBSD.ORG Tue Jan 20 05:44:22 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 03BE81C2; Tue, 20 Jan 2015 05:44:22 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E3D306C5; Tue, 20 Jan 2015 05:44:21 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0K5iLpl095580; Tue, 20 Jan 2015 05:44:21 GMT (envelope-from nwhitehorn@FreeBSD.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0K5iLdf095579; Tue, 20 Jan 2015 05:44:21 GMT (envelope-from nwhitehorn@FreeBSD.org) Message-Id: <201501200544.t0K5iLdf095579@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: nwhitehorn set sender to nwhitehorn@FreeBSD.org using -f From: Nathan Whitehorn Date: Tue, 20 Jan 2015 05:44:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277412 - head/sys/powerpc/ofw X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Jan 2015 05:44:22 -0000 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 #include #include +#include #include @@ -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; }