Page MenuHomeFreeBSD

D15610.diff
No OneTemporary

D15610.diff

Index: head/sys/powerpc/ofw/ofw_machdep.c
===================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c
+++ head/sys/powerpc/ofw/ofw_machdep.c
@@ -225,41 +225,19 @@
#ifdef FDT
static int
-excise_fdt_reserved(struct mem_region *avail, int asz)
+excise_reserved_regions(struct mem_region *avail, int asz,
+ struct mem_region *exclude, int esz)
{
- struct {
- uint64_t address;
- uint64_t size;
- } fdtmap[32];
- 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) & ~PAGE_MASK;
- fdtmap[j].size = round_page(be64toh(fdtmap[j].size));
- }
-
- KASSERT(j*sizeof(fdtmap[0]) < sizeof(fdtmap),
- ("Exceeded number of FDT reservations"));
- /* Add a virtual entry for the FDT itself */
- if (fdt != NULL) {
- fdtmap[j].address = (vm_offset_t)fdt & ~PAGE_MASK;
- fdtmap[j].size = round_page(fdt_totalsize(fdt));
- fdtmapsize += sizeof(fdtmap[0]);
- }
-
for (i = 0; i < asz; i++) {
- for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
+ for (j = 0; j < esz; 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 >=
+ if (exclude[j].mr_start <= avail[i].mr_start &&
+ exclude[j].mr_start + exclude[j].mr_size >=
avail[i].mr_start + avail[i].mr_size) {
for (k = i+1; k < asz; k++)
avail[k-1] = avail[k];
@@ -274,20 +252,20 @@
* 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 +
+ if (exclude[j].mr_start >= avail[i].mr_start &&
+ exclude[j].mr_start < avail[i].mr_start +
avail[i].mr_size) {
- if (fdtmap[j].address + fdtmap[j].size <
+ if (exclude[j].mr_start + exclude[j].mr_size <
avail[i].mr_start + avail[i].mr_size) {
avail[asz].mr_start =
- fdtmap[j].address + fdtmap[j].size;
+ exclude[j].mr_start + exclude[j].mr_size;
avail[asz].mr_size = avail[i].mr_start +
avail[i].mr_size -
avail[asz].mr_start;
asz++;
}
- avail[i].mr_size = fdtmap[j].address -
+ avail[i].mr_size = exclude[j].mr_start -
avail[i].mr_start;
}
@@ -297,13 +275,13 @@
* 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 +
+ if (exclude[j].mr_start + exclude[j].mr_size >=
+ avail[i].mr_start && exclude[j].mr_start +
+ exclude[j].mr_size < avail[i].mr_start +
avail[i].mr_size) {
avail[i].mr_size += avail[i].mr_start;
avail[i].mr_start =
- fdtmap[j].address + fdtmap[j].size;
+ exclude[j].mr_start + exclude[j].mr_size;
avail[i].mr_size -= avail[i].mr_start;
}
}
@@ -311,6 +289,62 @@
return (asz);
}
+
+static int
+excise_initrd_region(struct mem_region *avail, int asz)
+{
+ phandle_t chosen;
+ uint64_t start, end;
+ ssize_t size;
+ struct mem_region initrdmap[1];
+
+ chosen = OF_finddevice("/chosen");
+ size = OF_getprop(chosen, "linux,initrd-start", &start, sizeof(start));
+ if (size <= 0)
+ return (asz);
+
+ size = OF_getprop(chosen, "linux,initrd-end", &end, sizeof(end));
+ if (size <= 0)
+ return (asz);
+
+ initrdmap[0].mr_start = start;
+ initrdmap[0].mr_size = end - start;
+
+ asz = excise_reserved_regions(avail, asz, initrdmap, 1);
+
+ return (asz);
+}
+
+static int
+excise_fdt_reserved(struct mem_region *avail, int asz)
+{
+ struct mem_region fdtmap[32];
+ ssize_t fdtmapsize;
+ phandle_t chosen;
+ int j, fdtentries;
+
+ chosen = OF_finddevice("/chosen");
+ fdtmapsize = OF_getprop(chosen, "fdtmemreserv", fdtmap, sizeof(fdtmap));
+
+ for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
+ fdtmap[j].mr_start = be64toh(fdtmap[j].mr_start) & ~PAGE_MASK;
+ fdtmap[j].mr_size = round_page(be64toh(fdtmap[j].mr_size));
+ }
+
+ KASSERT(j*sizeof(fdtmap[0]) < sizeof(fdtmap),
+ ("Exceeded number of FDT reservations"));
+ /* Add a virtual entry for the FDT itself */
+ if (fdt != NULL) {
+ fdtmap[j].mr_start = (vm_offset_t)fdt & ~PAGE_MASK;
+ fdtmap[j].mr_size = round_page(fdt_totalsize(fdt));
+ fdtmapsize += sizeof(fdtmap[0]);
+ }
+
+ fdtentries = fdtmapsize/sizeof(fdtmap[0]);
+ asz = excise_reserved_regions(avail, asz, fdtmap, fdtentries);
+
+ return (asz);
+}
#endif
/*
@@ -364,6 +398,13 @@
phandle = OF_finddevice("/chosen");
if (OF_hasprop(phandle, "fdtmemreserv"))
asz = excise_fdt_reserved(availp, asz);
+
+ /* If the kernel is being loaded through kexec, initrd region is listed
+ * in /chosen but the region is not marked as reserved, so, we might exclude
+ * it here.
+ */
+ if (OF_hasprop(phandle, "linux,initrd-start"))
+ asz = excise_initrd_region(availp, asz);
#endif
*memsz = msz;

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 6:40 PM (2 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31926427
Default Alt Text
D15610.diff (5 KB)

Event Timeline