summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-11-30 03:11:03 +0000
committergonzo <gonzo@FreeBSD.org>2012-11-30 03:11:03 +0000
commitdf6a0a2978f573b82f6c7a317da896198d42df22 (patch)
tree2dd5bd1cf83330b92c78a41774d05c1cad114f8e /sys/arm
parentd948e0882e798da2fb0f38e973079ae7839f2115 (diff)
downloadFreeBSD-src-df6a0a2978f573b82f6c7a317da896198d42df22.zip
FreeBSD-src-df6a0a2978f573b82f6c7a317da896198d42df22.tar.gz
Get reserved memory regions and exclude them from available memory map
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/machdep.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 08d6fc1..e358f96 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -1144,7 +1144,9 @@ physmap_init(struct mem_region *availmem_regions, int availmem_regions_sz)
void *
initarm(struct arm_boot_params *abp)
{
+ struct mem_region memory_regions[FDT_MEM_REGIONS];
struct mem_region availmem_regions[FDT_MEM_REGIONS];
+ struct mem_region reserved_regions[FDT_MEM_REGIONS];
struct pv_addr kernel_l1pt;
struct pv_addr dpcpu;
vm_offset_t dtbp, freemempos, l2_start, lastaddr;
@@ -1154,7 +1156,12 @@ initarm(struct arm_boot_params *abp)
void *kmdp;
u_int l1pagetable;
int i = 0, j = 0, err_devmap = 0;
+ int memory_regions_sz;
int availmem_regions_sz;
+ int reserved_regions_sz;
+ vm_offset_t start, end;
+ vm_offset_t rstart, rend;
+ int curr;
lastaddr = parse_boot_param(abp);
memsize = 0;
@@ -1185,10 +1192,73 @@ initarm(struct arm_boot_params *abp)
while (1);
/* Grab physical memory regions information from device tree. */
- if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz,
+ if (fdt_get_mem_regions(memory_regions, &memory_regions_sz,
&memsize) != 0)
while(1);
+ /* Grab physical memory regions information from device tree. */
+ if (fdt_get_reserved_regions(reserved_regions, &reserved_regions_sz) != 0)
+ reserved_regions_sz = 0;
+
+ /*
+ * Now exclude all the reserved regions
+ */
+ curr = 0;
+ for (i = 0; i < memory_regions_sz; i++) {
+ start = memory_regions[i].mr_start;
+ end = start + memory_regions[i].mr_size;
+ for (j = 0; j < reserved_regions_sz; j++) {
+ rstart = reserved_regions[j].mr_start;
+ rend = rstart + reserved_regions[j].mr_size;
+ /*
+ * Restricted region is before available
+ * Skip restricted region
+ */
+ if (rend <= start)
+ continue;
+ /*
+ * Restricted region is behind available
+ * No further processing required
+ */
+ if (rstart >= end)
+ break;
+ /*
+ * Restricted region includes memory region
+ * skip availble region
+ */
+ if ((start >= rstart) && (rend >= end)) {
+ start = rend;
+ end = rend;
+ break;
+ }
+ /*
+ * Memory region includes restricted region
+ */
+ if ((rstart > start) && (end > rend)) {
+ availmem_regions[curr].mr_start = start;
+ availmem_regions[curr++].mr_size = rstart - start;
+ start = rend;
+ break;
+ }
+ /*
+ * Memory region partially overlaps with restricted
+ */
+ if ((rstart >= start) && (rstart <= end)) {
+ end = rstart;
+ }
+ else if ((rend >= start) && (rend <= end)) {
+ start = rend;
+ }
+ }
+
+ if (end > start) {
+ availmem_regions[curr].mr_start = start;
+ availmem_regions[curr++].mr_size = end - start;
+ }
+ }
+
+ availmem_regions_sz = curr;
+
/* Platform-specific initialisation */
pmap_bootstrap_lastaddr = initarm_lastaddr();
OpenPOWER on IntegriCloud